@fieldia/core 0.1.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/LICENSE +21 -0
- package/README.md +31 -0
- package/package.json +40 -0
- package/schema/page.schema.json +2142 -0
- package/src/index.d.mts +15 -0
- package/src/index.d.ts +15 -0
- package/src/index.js +46 -0
- package/src/index.js.map +1 -0
- package/src/index.mjs +14 -0
- package/src/index.mjs.map +1 -0
- package/src/lib/expression/evaluateModifier.d.mts +55 -0
- package/src/lib/expression/evaluateModifier.d.ts +55 -0
- package/src/lib/expression/evaluateModifier.js +121 -0
- package/src/lib/expression/evaluateModifier.js.map +1 -0
- package/src/lib/expression/evaluateModifier.mjs +117 -0
- package/src/lib/expression/evaluateModifier.mjs.map +1 -0
- package/src/lib/expression/evaluator.d.mts +23 -0
- package/src/lib/expression/evaluator.d.ts +23 -0
- package/src/lib/expression/evaluator.js +122 -0
- package/src/lib/expression/evaluator.js.map +1 -0
- package/src/lib/expression/evaluator.mjs +118 -0
- package/src/lib/expression/evaluator.mjs.map +1 -0
- package/src/lib/expression/extractFieldNames.d.mts +41 -0
- package/src/lib/expression/extractFieldNames.d.ts +41 -0
- package/src/lib/expression/extractFieldNames.js +97 -0
- package/src/lib/expression/extractFieldNames.js.map +1 -0
- package/src/lib/expression/extractFieldNames.mjs +93 -0
- package/src/lib/expression/extractFieldNames.mjs.map +1 -0
- package/src/lib/expression/modifier.d.mts +14 -0
- package/src/lib/expression/modifier.d.ts +14 -0
- package/src/lib/expression/modifier.js +55 -0
- package/src/lib/expression/modifier.js.map +1 -0
- package/src/lib/expression/modifier.mjs +52 -0
- package/src/lib/expression/modifier.mjs.map +1 -0
- package/src/lib/expression/parser.d.mts +109 -0
- package/src/lib/expression/parser.d.ts +109 -0
- package/src/lib/expression/parser.js +317 -0
- package/src/lib/expression/parser.js.map +1 -0
- package/src/lib/expression/parser.mjs +313 -0
- package/src/lib/expression/parser.mjs.map +1 -0
- package/src/lib/expression/tokenizer.d.mts +31 -0
- package/src/lib/expression/tokenizer.d.ts +31 -0
- package/src/lib/expression/tokenizer.js +100 -0
- package/src/lib/expression/tokenizer.js.map +1 -0
- package/src/lib/expression/tokenizer.mjs +96 -0
- package/src/lib/expression/tokenizer.mjs.map +1 -0
- package/src/lib/format/field.d.mts +967 -0
- package/src/lib/format/field.d.ts +967 -0
- package/src/lib/format/field.js +147 -0
- package/src/lib/format/field.js.map +1 -0
- package/src/lib/format/field.mjs +144 -0
- package/src/lib/format/field.mjs.map +1 -0
- package/src/lib/format/json-schema.d.mts +6 -0
- package/src/lib/format/json-schema.d.ts +6 -0
- package/src/lib/format/json-schema.js +14 -0
- package/src/lib/format/json-schema.js.map +1 -0
- package/src/lib/format/json-schema.mjs +11 -0
- package/src/lib/format/json-schema.mjs.map +1 -0
- package/src/lib/format/json.d.mts +7 -0
- package/src/lib/format/json.d.ts +7 -0
- package/src/lib/format/json.js +7 -0
- package/src/lib/format/json.js.map +1 -0
- package/src/lib/format/json.mjs +4 -0
- package/src/lib/format/json.mjs.map +1 -0
- package/src/lib/format/layout.d.mts +521 -0
- package/src/lib/format/layout.d.ts +521 -0
- package/src/lib/format/layout.js +150 -0
- package/src/lib/format/layout.js.map +1 -0
- package/src/lib/format/layout.mjs +147 -0
- package/src/lib/format/layout.mjs.map +1 -0
- package/src/lib/format/layout.types.d.mts +22 -0
- package/src/lib/format/layout.types.d.ts +22 -0
- package/src/lib/format/layout.types.js +3 -0
- package/src/lib/format/layout.types.js.map +1 -0
- package/src/lib/format/layout.types.mjs +2 -0
- package/src/lib/format/layout.types.mjs.map +1 -0
- package/src/lib/format/page.d.mts +511 -0
- package/src/lib/format/page.d.ts +511 -0
- package/src/lib/format/page.js +27 -0
- package/src/lib/format/page.js.map +1 -0
- package/src/lib/format/page.mjs +24 -0
- package/src/lib/format/page.mjs.map +1 -0
- package/src/lib/format/validate.d.mts +23 -0
- package/src/lib/format/validate.d.ts +23 -0
- package/src/lib/format/validate.js +210 -0
- package/src/lib/format/validate.js.map +1 -0
- package/src/lib/format/validate.mjs +207 -0
- package/src/lib/format/validate.mjs.map +1 -0
- package/src/lib/record/check.d.mts +14 -0
- package/src/lib/record/check.d.ts +14 -0
- package/src/lib/record/check.js +167 -0
- package/src/lib/record/check.js.map +1 -0
- package/src/lib/record/check.mjs +163 -0
- package/src/lib/record/check.mjs.map +1 -0
- package/src/lib/record/data-source.d.mts +109 -0
- package/src/lib/record/data-source.d.ts +109 -0
- package/src/lib/record/data-source.js +3 -0
- package/src/lib/record/data-source.js.map +1 -0
- package/src/lib/record/data-source.mjs +2 -0
- package/src/lib/record/data-source.mjs.map +1 -0
- package/src/lib/record/form.d.mts +106 -0
- package/src/lib/record/form.d.ts +106 -0
- package/src/lib/record/form.js +545 -0
- package/src/lib/record/form.js.map +1 -0
- package/src/lib/record/form.mjs +542 -0
- package/src/lib/record/form.mjs.map +1 -0
- package/src/lib/record/memory-data-source.d.mts +28 -0
- package/src/lib/record/memory-data-source.d.ts +28 -0
- package/src/lib/record/memory-data-source.js +132 -0
- package/src/lib/record/memory-data-source.js.map +1 -0
- package/src/lib/record/memory-data-source.mjs +129 -0
- package/src/lib/record/memory-data-source.mjs.map +1 -0
- package/src/lib/record/messages.d.mts +35 -0
- package/src/lib/record/messages.d.ts +35 -0
- package/src/lib/record/messages.js +111 -0
- package/src/lib/record/messages.js.map +1 -0
- package/src/lib/record/messages.mjs +107 -0
- package/src/lib/record/messages.mjs.map +1 -0
- package/src/lib/record/scheduler.d.mts +12 -0
- package/src/lib/record/scheduler.d.ts +12 -0
- package/src/lib/record/scheduler.js +16 -0
- package/src/lib/record/scheduler.js.map +1 -0
- package/src/lib/record/scheduler.mjs +12 -0
- package/src/lib/record/scheduler.mjs.map +1 -0
- package/src/lib/record/values.d.mts +54 -0
- package/src/lib/record/values.d.ts +54 -0
- package/src/lib/record/values.js +78 -0
- package/src/lib/record/values.js.map +1 -0
- package/src/lib/record/values.mjs +71 -0
- package/src/lib/record/values.mjs.map +1 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** The host's own timers: the browser's or Node's, whichever is running. */
|
|
2
|
+
export const hostScheduler = {
|
|
3
|
+
setTimeout: (callback, ms) => globalThis.setTimeout(callback, ms),
|
|
4
|
+
clearTimeout: (handle) => globalThis.clearTimeout(handle),
|
|
5
|
+
};
|
|
6
|
+
/** Resolve after `ms`, on the given scheduler. */
|
|
7
|
+
export function wait(ms, scheduler = hostScheduler) {
|
|
8
|
+
return new Promise((resolve) => {
|
|
9
|
+
scheduler.setTimeout(resolve, ms);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=scheduler.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.mjs","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/scheduler.ts"],"names":[],"mappings":"AAcA,4EAA4E;AAC5E,MAAM,CAAC,MAAM,aAAa,GAAc;IACtC,UAAU,EAAE,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAE,UAAoC,CAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC5F,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE,CAAE,UAAoC,CAAC,YAAY,CAAC,MAAM,CAAC;CACrF,CAAC;AAEF,kDAAkD;AAClD,MAAM,UAAU,IAAI,CAAC,EAAU,EAAE,YAAuB,aAAa;IACnE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,SAAS,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Field, LineField } from '../format/field.mjs';
|
|
2
|
+
import type { JsonValue } from '../format/json.mjs';
|
|
3
|
+
/**
|
|
4
|
+
* The values a form holds while someone edits it. Plain JSON, so a draft can
|
|
5
|
+
* be stored and a record handed to any data source.
|
|
6
|
+
*/
|
|
7
|
+
export type RecordId = number | string;
|
|
8
|
+
/** A related record, as a many2one or many2many holds it: enough to show it. */
|
|
9
|
+
export interface RelatedRecord {
|
|
10
|
+
id: RecordId;
|
|
11
|
+
label: string;
|
|
12
|
+
}
|
|
13
|
+
/** A reference points at a record of one of several models. */
|
|
14
|
+
export interface ReferenceValue {
|
|
15
|
+
model: string;
|
|
16
|
+
id: RecordId;
|
|
17
|
+
label: string;
|
|
18
|
+
}
|
|
19
|
+
/** An uploaded or stored file. `data` is base64; `url` is where a stored one lives. */
|
|
20
|
+
export interface FileValue {
|
|
21
|
+
name: string;
|
|
22
|
+
type: string;
|
|
23
|
+
size: number;
|
|
24
|
+
data?: string;
|
|
25
|
+
url?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* One line of a one2many. `key` is stable for the life of the form, so a line
|
|
29
|
+
* keeps its identity while it is edited; `id` is the saved record's id, absent
|
|
30
|
+
* until the line is saved.
|
|
31
|
+
*/
|
|
32
|
+
export interface Line {
|
|
33
|
+
key: string;
|
|
34
|
+
id?: RecordId;
|
|
35
|
+
values: Values;
|
|
36
|
+
}
|
|
37
|
+
export type Value = JsonValue | RelatedRecord | RelatedRecord[] | ReferenceValue | FileValue | Line[];
|
|
38
|
+
export type Values = Record<string, Value>;
|
|
39
|
+
type AnyField = Field | LineField;
|
|
40
|
+
/** What a field holds before anyone types in it. */
|
|
41
|
+
export declare function emptyValue(field: AnyField): Value;
|
|
42
|
+
/** A fresh record: each field's default, or its empty value. */
|
|
43
|
+
export declare function initialValues(fields: Record<string, AnyField>): Values;
|
|
44
|
+
/** Nothing worth keeping: no value, blank text, or an empty list. Numbers and booleans never are. */
|
|
45
|
+
export declare function isEmpty(_field: AnyField, value: Value | undefined): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* The values as modifiers read them, matching what backends write in their
|
|
48
|
+
* expressions: a many2one is its id, a many2many its ids, a reference
|
|
49
|
+
* "model,id", a file its name, and lines a list (so `not child_ids` works).
|
|
50
|
+
*/
|
|
51
|
+
export declare function expressionContext(values: Values, fields: Record<string, AnyField>): Record<string, unknown>;
|
|
52
|
+
/** A deep copy of plain JSON. */
|
|
53
|
+
export declare function structuredCopy<T>(value: T): T;
|
|
54
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Field, LineField } from '../format/field';
|
|
2
|
+
import type { JsonValue } from '../format/json';
|
|
3
|
+
/**
|
|
4
|
+
* The values a form holds while someone edits it. Plain JSON, so a draft can
|
|
5
|
+
* be stored and a record handed to any data source.
|
|
6
|
+
*/
|
|
7
|
+
export type RecordId = number | string;
|
|
8
|
+
/** A related record, as a many2one or many2many holds it: enough to show it. */
|
|
9
|
+
export interface RelatedRecord {
|
|
10
|
+
id: RecordId;
|
|
11
|
+
label: string;
|
|
12
|
+
}
|
|
13
|
+
/** A reference points at a record of one of several models. */
|
|
14
|
+
export interface ReferenceValue {
|
|
15
|
+
model: string;
|
|
16
|
+
id: RecordId;
|
|
17
|
+
label: string;
|
|
18
|
+
}
|
|
19
|
+
/** An uploaded or stored file. `data` is base64; `url` is where a stored one lives. */
|
|
20
|
+
export interface FileValue {
|
|
21
|
+
name: string;
|
|
22
|
+
type: string;
|
|
23
|
+
size: number;
|
|
24
|
+
data?: string;
|
|
25
|
+
url?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* One line of a one2many. `key` is stable for the life of the form, so a line
|
|
29
|
+
* keeps its identity while it is edited; `id` is the saved record's id, absent
|
|
30
|
+
* until the line is saved.
|
|
31
|
+
*/
|
|
32
|
+
export interface Line {
|
|
33
|
+
key: string;
|
|
34
|
+
id?: RecordId;
|
|
35
|
+
values: Values;
|
|
36
|
+
}
|
|
37
|
+
export type Value = JsonValue | RelatedRecord | RelatedRecord[] | ReferenceValue | FileValue | Line[];
|
|
38
|
+
export type Values = Record<string, Value>;
|
|
39
|
+
type AnyField = Field | LineField;
|
|
40
|
+
/** What a field holds before anyone types in it. */
|
|
41
|
+
export declare function emptyValue(field: AnyField): Value;
|
|
42
|
+
/** A fresh record: each field's default, or its empty value. */
|
|
43
|
+
export declare function initialValues(fields: Record<string, AnyField>): Values;
|
|
44
|
+
/** Nothing worth keeping: no value, blank text, or an empty list. Numbers and booleans never are. */
|
|
45
|
+
export declare function isEmpty(_field: AnyField, value: Value | undefined): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* The values as modifiers read them, matching what backends write in their
|
|
48
|
+
* expressions: a many2one is its id, a many2many its ids, a reference
|
|
49
|
+
* "model,id", a file its name, and lines a list (so `not child_ids` works).
|
|
50
|
+
*/
|
|
51
|
+
export declare function expressionContext(values: Values, fields: Record<string, AnyField>): Record<string, unknown>;
|
|
52
|
+
/** A deep copy of plain JSON. */
|
|
53
|
+
export declare function structuredCopy<T>(value: T): T;
|
|
54
|
+
export {};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.emptyValue = emptyValue;
|
|
4
|
+
exports.initialValues = initialValues;
|
|
5
|
+
exports.isEmpty = isEmpty;
|
|
6
|
+
exports.expressionContext = expressionContext;
|
|
7
|
+
exports.structuredCopy = structuredCopy;
|
|
8
|
+
/** What a field holds before anyone types in it. */
|
|
9
|
+
function emptyValue(field) {
|
|
10
|
+
switch (field.type) {
|
|
11
|
+
case 'boolean':
|
|
12
|
+
return false;
|
|
13
|
+
case 'many2many':
|
|
14
|
+
case 'one2many':
|
|
15
|
+
return [];
|
|
16
|
+
case 'selection':
|
|
17
|
+
return field.multiple ? [] : null;
|
|
18
|
+
default:
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** A fresh record: each field's default, or its empty value. */
|
|
23
|
+
function initialValues(fields) {
|
|
24
|
+
const values = {};
|
|
25
|
+
for (const [name, field] of Object.entries(fields)) {
|
|
26
|
+
values[name] = field.default !== undefined ? structuredCopy(field.default) : emptyValue(field);
|
|
27
|
+
}
|
|
28
|
+
return values;
|
|
29
|
+
}
|
|
30
|
+
/** Nothing worth keeping: no value, blank text, or an empty list. Numbers and booleans never are. */
|
|
31
|
+
function isEmpty(_field, value) {
|
|
32
|
+
if (value === null || value === undefined)
|
|
33
|
+
return true;
|
|
34
|
+
if (typeof value === 'string')
|
|
35
|
+
return value.trim() === '';
|
|
36
|
+
if (Array.isArray(value))
|
|
37
|
+
return value.length === 0;
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The values as modifiers read them, matching what backends write in their
|
|
42
|
+
* expressions: a many2one is its id, a many2many its ids, a reference
|
|
43
|
+
* "model,id", a file its name, and lines a list (so `not child_ids` works).
|
|
44
|
+
*/
|
|
45
|
+
function expressionContext(values, fields) {
|
|
46
|
+
const context = {};
|
|
47
|
+
for (const [name, value] of Object.entries(values)) {
|
|
48
|
+
const field = fields[name];
|
|
49
|
+
context[name] = field ? forExpressions(field, value) : value;
|
|
50
|
+
}
|
|
51
|
+
return context;
|
|
52
|
+
}
|
|
53
|
+
function forExpressions(field, value) {
|
|
54
|
+
if (value === null || value === undefined)
|
|
55
|
+
return null;
|
|
56
|
+
switch (field.type) {
|
|
57
|
+
case 'many2one':
|
|
58
|
+
return value.id;
|
|
59
|
+
case 'many2many':
|
|
60
|
+
return value.map((record) => record.id);
|
|
61
|
+
case 'one2many':
|
|
62
|
+
return value.map((line) => line.key);
|
|
63
|
+
case 'reference': {
|
|
64
|
+
const ref = value;
|
|
65
|
+
return `${ref.model},${ref.id}`;
|
|
66
|
+
}
|
|
67
|
+
case 'binary':
|
|
68
|
+
case 'image':
|
|
69
|
+
return value.name;
|
|
70
|
+
default:
|
|
71
|
+
return value;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/** A deep copy of plain JSON. */
|
|
75
|
+
function structuredCopy(value) {
|
|
76
|
+
return value === undefined ? value : JSON.parse(JSON.stringify(value));
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=values.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"values.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/values.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/** What a field holds before anyone types in it. */
|
|
2
|
+
export function emptyValue(field) {
|
|
3
|
+
switch (field.type) {
|
|
4
|
+
case 'boolean':
|
|
5
|
+
return false;
|
|
6
|
+
case 'many2many':
|
|
7
|
+
case 'one2many':
|
|
8
|
+
return [];
|
|
9
|
+
case 'selection':
|
|
10
|
+
return field.multiple ? [] : null;
|
|
11
|
+
default:
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/** A fresh record: each field's default, or its empty value. */
|
|
16
|
+
export function initialValues(fields) {
|
|
17
|
+
const values = {};
|
|
18
|
+
for (const [name, field] of Object.entries(fields)) {
|
|
19
|
+
values[name] = field.default !== undefined ? structuredCopy(field.default) : emptyValue(field);
|
|
20
|
+
}
|
|
21
|
+
return values;
|
|
22
|
+
}
|
|
23
|
+
/** Nothing worth keeping: no value, blank text, or an empty list. Numbers and booleans never are. */
|
|
24
|
+
export function isEmpty(_field, value) {
|
|
25
|
+
if (value === null || value === undefined)
|
|
26
|
+
return true;
|
|
27
|
+
if (typeof value === 'string')
|
|
28
|
+
return value.trim() === '';
|
|
29
|
+
if (Array.isArray(value))
|
|
30
|
+
return value.length === 0;
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The values as modifiers read them, matching what backends write in their
|
|
35
|
+
* expressions: a many2one is its id, a many2many its ids, a reference
|
|
36
|
+
* "model,id", a file its name, and lines a list (so `not child_ids` works).
|
|
37
|
+
*/
|
|
38
|
+
export function expressionContext(values, fields) {
|
|
39
|
+
const context = {};
|
|
40
|
+
for (const [name, value] of Object.entries(values)) {
|
|
41
|
+
const field = fields[name];
|
|
42
|
+
context[name] = field ? forExpressions(field, value) : value;
|
|
43
|
+
}
|
|
44
|
+
return context;
|
|
45
|
+
}
|
|
46
|
+
function forExpressions(field, value) {
|
|
47
|
+
if (value === null || value === undefined)
|
|
48
|
+
return null;
|
|
49
|
+
switch (field.type) {
|
|
50
|
+
case 'many2one':
|
|
51
|
+
return value.id;
|
|
52
|
+
case 'many2many':
|
|
53
|
+
return value.map((record) => record.id);
|
|
54
|
+
case 'one2many':
|
|
55
|
+
return value.map((line) => line.key);
|
|
56
|
+
case 'reference': {
|
|
57
|
+
const ref = value;
|
|
58
|
+
return `${ref.model},${ref.id}`;
|
|
59
|
+
}
|
|
60
|
+
case 'binary':
|
|
61
|
+
case 'image':
|
|
62
|
+
return value.name;
|
|
63
|
+
default:
|
|
64
|
+
return value;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** A deep copy of plain JSON. */
|
|
68
|
+
export function structuredCopy(value) {
|
|
69
|
+
return value === undefined ? value : JSON.parse(JSON.stringify(value));
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=values.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"values.mjs","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/values.ts"],"names":[],"mappings":"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"}
|