@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.
Files changed (130) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +31 -0
  3. package/package.json +40 -0
  4. package/schema/page.schema.json +2142 -0
  5. package/src/index.d.mts +15 -0
  6. package/src/index.d.ts +15 -0
  7. package/src/index.js +46 -0
  8. package/src/index.js.map +1 -0
  9. package/src/index.mjs +14 -0
  10. package/src/index.mjs.map +1 -0
  11. package/src/lib/expression/evaluateModifier.d.mts +55 -0
  12. package/src/lib/expression/evaluateModifier.d.ts +55 -0
  13. package/src/lib/expression/evaluateModifier.js +121 -0
  14. package/src/lib/expression/evaluateModifier.js.map +1 -0
  15. package/src/lib/expression/evaluateModifier.mjs +117 -0
  16. package/src/lib/expression/evaluateModifier.mjs.map +1 -0
  17. package/src/lib/expression/evaluator.d.mts +23 -0
  18. package/src/lib/expression/evaluator.d.ts +23 -0
  19. package/src/lib/expression/evaluator.js +122 -0
  20. package/src/lib/expression/evaluator.js.map +1 -0
  21. package/src/lib/expression/evaluator.mjs +118 -0
  22. package/src/lib/expression/evaluator.mjs.map +1 -0
  23. package/src/lib/expression/extractFieldNames.d.mts +41 -0
  24. package/src/lib/expression/extractFieldNames.d.ts +41 -0
  25. package/src/lib/expression/extractFieldNames.js +97 -0
  26. package/src/lib/expression/extractFieldNames.js.map +1 -0
  27. package/src/lib/expression/extractFieldNames.mjs +93 -0
  28. package/src/lib/expression/extractFieldNames.mjs.map +1 -0
  29. package/src/lib/expression/modifier.d.mts +14 -0
  30. package/src/lib/expression/modifier.d.ts +14 -0
  31. package/src/lib/expression/modifier.js +55 -0
  32. package/src/lib/expression/modifier.js.map +1 -0
  33. package/src/lib/expression/modifier.mjs +52 -0
  34. package/src/lib/expression/modifier.mjs.map +1 -0
  35. package/src/lib/expression/parser.d.mts +109 -0
  36. package/src/lib/expression/parser.d.ts +109 -0
  37. package/src/lib/expression/parser.js +317 -0
  38. package/src/lib/expression/parser.js.map +1 -0
  39. package/src/lib/expression/parser.mjs +313 -0
  40. package/src/lib/expression/parser.mjs.map +1 -0
  41. package/src/lib/expression/tokenizer.d.mts +31 -0
  42. package/src/lib/expression/tokenizer.d.ts +31 -0
  43. package/src/lib/expression/tokenizer.js +100 -0
  44. package/src/lib/expression/tokenizer.js.map +1 -0
  45. package/src/lib/expression/tokenizer.mjs +96 -0
  46. package/src/lib/expression/tokenizer.mjs.map +1 -0
  47. package/src/lib/format/field.d.mts +967 -0
  48. package/src/lib/format/field.d.ts +967 -0
  49. package/src/lib/format/field.js +147 -0
  50. package/src/lib/format/field.js.map +1 -0
  51. package/src/lib/format/field.mjs +144 -0
  52. package/src/lib/format/field.mjs.map +1 -0
  53. package/src/lib/format/json-schema.d.mts +6 -0
  54. package/src/lib/format/json-schema.d.ts +6 -0
  55. package/src/lib/format/json-schema.js +14 -0
  56. package/src/lib/format/json-schema.js.map +1 -0
  57. package/src/lib/format/json-schema.mjs +11 -0
  58. package/src/lib/format/json-schema.mjs.map +1 -0
  59. package/src/lib/format/json.d.mts +7 -0
  60. package/src/lib/format/json.d.ts +7 -0
  61. package/src/lib/format/json.js +7 -0
  62. package/src/lib/format/json.js.map +1 -0
  63. package/src/lib/format/json.mjs +4 -0
  64. package/src/lib/format/json.mjs.map +1 -0
  65. package/src/lib/format/layout.d.mts +521 -0
  66. package/src/lib/format/layout.d.ts +521 -0
  67. package/src/lib/format/layout.js +150 -0
  68. package/src/lib/format/layout.js.map +1 -0
  69. package/src/lib/format/layout.mjs +147 -0
  70. package/src/lib/format/layout.mjs.map +1 -0
  71. package/src/lib/format/layout.types.d.mts +22 -0
  72. package/src/lib/format/layout.types.d.ts +22 -0
  73. package/src/lib/format/layout.types.js +3 -0
  74. package/src/lib/format/layout.types.js.map +1 -0
  75. package/src/lib/format/layout.types.mjs +2 -0
  76. package/src/lib/format/layout.types.mjs.map +1 -0
  77. package/src/lib/format/page.d.mts +511 -0
  78. package/src/lib/format/page.d.ts +511 -0
  79. package/src/lib/format/page.js +27 -0
  80. package/src/lib/format/page.js.map +1 -0
  81. package/src/lib/format/page.mjs +24 -0
  82. package/src/lib/format/page.mjs.map +1 -0
  83. package/src/lib/format/validate.d.mts +23 -0
  84. package/src/lib/format/validate.d.ts +23 -0
  85. package/src/lib/format/validate.js +210 -0
  86. package/src/lib/format/validate.js.map +1 -0
  87. package/src/lib/format/validate.mjs +207 -0
  88. package/src/lib/format/validate.mjs.map +1 -0
  89. package/src/lib/record/check.d.mts +14 -0
  90. package/src/lib/record/check.d.ts +14 -0
  91. package/src/lib/record/check.js +167 -0
  92. package/src/lib/record/check.js.map +1 -0
  93. package/src/lib/record/check.mjs +163 -0
  94. package/src/lib/record/check.mjs.map +1 -0
  95. package/src/lib/record/data-source.d.mts +109 -0
  96. package/src/lib/record/data-source.d.ts +109 -0
  97. package/src/lib/record/data-source.js +3 -0
  98. package/src/lib/record/data-source.js.map +1 -0
  99. package/src/lib/record/data-source.mjs +2 -0
  100. package/src/lib/record/data-source.mjs.map +1 -0
  101. package/src/lib/record/form.d.mts +106 -0
  102. package/src/lib/record/form.d.ts +106 -0
  103. package/src/lib/record/form.js +545 -0
  104. package/src/lib/record/form.js.map +1 -0
  105. package/src/lib/record/form.mjs +542 -0
  106. package/src/lib/record/form.mjs.map +1 -0
  107. package/src/lib/record/memory-data-source.d.mts +28 -0
  108. package/src/lib/record/memory-data-source.d.ts +28 -0
  109. package/src/lib/record/memory-data-source.js +132 -0
  110. package/src/lib/record/memory-data-source.js.map +1 -0
  111. package/src/lib/record/memory-data-source.mjs +129 -0
  112. package/src/lib/record/memory-data-source.mjs.map +1 -0
  113. package/src/lib/record/messages.d.mts +35 -0
  114. package/src/lib/record/messages.d.ts +35 -0
  115. package/src/lib/record/messages.js +111 -0
  116. package/src/lib/record/messages.js.map +1 -0
  117. package/src/lib/record/messages.mjs +107 -0
  118. package/src/lib/record/messages.mjs.map +1 -0
  119. package/src/lib/record/scheduler.d.mts +12 -0
  120. package/src/lib/record/scheduler.d.ts +12 -0
  121. package/src/lib/record/scheduler.js +16 -0
  122. package/src/lib/record/scheduler.js.map +1 -0
  123. package/src/lib/record/scheduler.mjs +12 -0
  124. package/src/lib/record/scheduler.mjs.map +1 -0
  125. package/src/lib/record/values.d.mts +54 -0
  126. package/src/lib/record/values.d.ts +54 -0
  127. package/src/lib/record/values.js +78 -0
  128. package/src/lib/record/values.js.map +1 -0
  129. package/src/lib/record/values.mjs +71 -0
  130. package/src/lib/record/values.mjs.map +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,163 @@
1
+ import { fill, MESSAGES } from './messages.mjs';
2
+ import { isEmpty } from './values.mjs';
3
+ /**
4
+ * Check one value against its field. Returns the message to show, or
5
+ * undefined when the value is fine. The wording follows the React engine's
6
+ * ("Name is required", "Maximum 120 characters allowed").
7
+ *
8
+ * An empty optional value passes everything: a pattern or a minimum applies
9
+ * to what someone typed, not to a field they left alone.
10
+ */
11
+ export function checkValue(field, value, required, messages = MESSAGES.en) {
12
+ const label = field.label || 'This field';
13
+ const say = (key, values = {}) => fill(messages[key], { label, ...values });
14
+ if (isEmpty(field, value))
15
+ return required ? say('required') : undefined;
16
+ switch (field.type) {
17
+ case 'char':
18
+ case 'text':
19
+ case 'html': {
20
+ if (typeof value !== 'string')
21
+ return say('text');
22
+ if ((field.type === 'char' || field.type === 'text') && field.size !== undefined && value.length > field.size) {
23
+ return say('maxLength', { max: field.size });
24
+ }
25
+ if (field.type === 'char' && field.pattern !== undefined && !new RegExp(field.pattern).test(value)) {
26
+ return say('pattern');
27
+ }
28
+ return undefined;
29
+ }
30
+ case 'integer':
31
+ case 'float':
32
+ case 'monetary': {
33
+ if (typeof value !== 'number' || !Number.isFinite(value))
34
+ return say('number');
35
+ if (field.type === 'integer' && !Number.isInteger(value))
36
+ return say('integer');
37
+ if (field.min !== undefined && value < field.min)
38
+ return say('min', { min: field.min });
39
+ if (field.max !== undefined && value > field.max)
40
+ return say('max', { max: field.max });
41
+ if (field.type !== 'integer' && field.digits && decimals(value) > field.digits[1]) {
42
+ return say('decimals', { digits: field.digits[1] });
43
+ }
44
+ return undefined;
45
+ }
46
+ case 'boolean':
47
+ return typeof value === 'boolean' ? undefined : say('boolean');
48
+ case 'date':
49
+ return checkDate(value, say);
50
+ case 'datetime':
51
+ return checkDateTime(value, say);
52
+ case 'selection': {
53
+ const allowed = new Set(field.options.map((o) => o.value));
54
+ const listing = say('choice', { options: field.options.map((o) => o.label).join(', ') });
55
+ if (field.multiple) {
56
+ if (!Array.isArray(value))
57
+ return say('choices');
58
+ return value.every((v) => allowed.has(v)) ? undefined : listing;
59
+ }
60
+ return allowed.has(value) ? undefined : listing;
61
+ }
62
+ case 'many2one':
63
+ return isRecord(value) ? undefined : say('record');
64
+ case 'many2many':
65
+ return Array.isArray(value) && value.every(isRecord) ? undefined : say('records');
66
+ case 'reference': {
67
+ const ref = value;
68
+ if (!isRecord(value) || typeof ref.model !== 'string')
69
+ return say('record');
70
+ if (!field.models.some((m) => m.value === ref.model)) {
71
+ const models = listOr(field.models.map((m) => m.label), messages.or);
72
+ return say('reference', { models, aModels: article(models) });
73
+ }
74
+ return undefined;
75
+ }
76
+ case 'binary':
77
+ case 'image':
78
+ return checkFile(field, value, say, messages);
79
+ default:
80
+ return undefined;
81
+ }
82
+ }
83
+ function decimals(value) {
84
+ const text = String(value);
85
+ if (text.includes('e-'))
86
+ return Number(text.split('e-')[1]);
87
+ const dot = text.indexOf('.');
88
+ return dot === -1 ? 0 : text.length - dot - 1;
89
+ }
90
+ function isRecord(value) {
91
+ return (value !== null &&
92
+ typeof value === 'object' &&
93
+ !Array.isArray(value) &&
94
+ (typeof value.id === 'number' || typeof value.id === 'string') &&
95
+ typeof value.label === 'string');
96
+ }
97
+ function checkDate(value, say) {
98
+ if (typeof value !== 'string' || !/^\d{4}-\d{2}-\d{2}$/.test(value))
99
+ return say('dateFormat');
100
+ const [y, m, d] = value.split('-').map(Number);
101
+ return realDay(y, m, d) ? undefined : say('dateInvalid');
102
+ }
103
+ const ISO_DATETIME = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2})(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:\d{2})?$/;
104
+ function checkDateTime(value, say) {
105
+ const match = typeof value === 'string' ? ISO_DATETIME.exec(value) : null;
106
+ if (!match)
107
+ return say('datetimeFormat');
108
+ const [y, mo, d, h, mi, s] = match.slice(1).map((part) => Number(part ?? 0));
109
+ return realDay(y, mo, d) && h < 24 && mi < 60 && s < 60 ? undefined : say('datetimeInvalid');
110
+ }
111
+ function realDay(year, month, day) {
112
+ if (month < 1 || month > 12 || day < 1)
113
+ return false;
114
+ const lengths = [31, year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
115
+ return day <= lengths[month - 1];
116
+ }
117
+ function checkFile(field, value, say, messages) {
118
+ const file = value;
119
+ if (!isFile(value))
120
+ return say('file');
121
+ if ('maxSize' in field && field.maxSize !== undefined && file.size > field.maxSize) {
122
+ return say('fileSize', { size: formatBytes(field.maxSize) });
123
+ }
124
+ if (field.type === 'binary' && field.accept && !field.accept.some((pattern) => matchesType(pattern, file.type))) {
125
+ const types = listOr(field.accept.map(describeType), messages.or);
126
+ return say('fileType', { types, aTypes: article(types) });
127
+ }
128
+ return undefined;
129
+ }
130
+ function isFile(value) {
131
+ const file = value;
132
+ return value !== null && typeof value === 'object' && typeof file.name === 'string' && typeof file.size === 'number';
133
+ }
134
+ function matchesType(pattern, type) {
135
+ return pattern.endsWith('/*') ? type.startsWith(pattern.slice(0, -1)) : pattern === type;
136
+ }
137
+ function describeType(pattern) {
138
+ if (pattern.endsWith('/*'))
139
+ return pattern.slice(0, -2);
140
+ if (pattern === 'application/pdf')
141
+ return 'PDF';
142
+ return (pattern.split('/')[1] ?? pattern).toUpperCase();
143
+ }
144
+ function listOr(items, or) {
145
+ if (items.length <= 1)
146
+ return items.join('');
147
+ return `${items.slice(0, -1).join(', ')} ${or} ${items[items.length - 1]}`;
148
+ }
149
+ function article(phrase) {
150
+ return /^[aeiou]/i.test(phrase) ? `an ${phrase}` : `a ${phrase}`;
151
+ }
152
+ /** 1048576 -> "1 MB". */
153
+ export function formatBytes(bytes) {
154
+ const units = ['bytes', 'KB', 'MB', 'GB'];
155
+ let size = bytes;
156
+ let unit = 0;
157
+ while (size >= 1024 && unit < units.length - 1) {
158
+ size /= 1024;
159
+ unit++;
160
+ }
161
+ return `${Number(size.toFixed(1))} ${units[unit]}`;
162
+ }
163
+ //# sourceMappingURL=check.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.mjs","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ import type { FilterCondition, Fields } from '../format/field.mjs';
2
+ import type { JsonValue } from '../format/json.mjs';
3
+ import type { RecordId, RelatedRecord, Values } from './values.mjs';
4
+ /**
5
+ * How Fieldia reaches data. Fieldia knows no backend: an app implements this
6
+ * interface for its own (a Flectra adapter, a REST client, a survey store),
7
+ * and every method is optional so a page uses only what it needs.
8
+ */
9
+ export interface DataSource {
10
+ /** Read a record. Needed to edit an existing record. */
11
+ load?(request: LoadRequest): Promise<Values>;
12
+ /** Create (`id: null`) or update a record. Needed to save a record page. */
13
+ save?(request: SaveRequest): Promise<SaveResult>;
14
+ /** Recalculate after a value changes, the way a backend's onchange does. */
15
+ onchange?(request: OnchangeRequest): Promise<OnchangeResult>;
16
+ /** Find records a many2one, many2many or reference may point to. */
17
+ search?(request: SearchRequest): Promise<RelatedRecord[]>;
18
+ /** Store one response to a `responses` page, such as a survey. */
19
+ submit?(request: SubmitRequest): Promise<SubmitResult>;
20
+ }
21
+ export interface LoadRequest {
22
+ model: string;
23
+ id: RecordId;
24
+ /** The page's fields, so the source reads exactly what the page shows. */
25
+ fields: Fields;
26
+ }
27
+ export interface SaveRequest {
28
+ model: string;
29
+ id: RecordId | null;
30
+ /** The page's fields, so the source knows each relation's model. */
31
+ fields: Fields;
32
+ /** Only what changed since the record was loaded or last saved. */
33
+ changes: RecordChanges;
34
+ /** Every value, for sources that save whole records. */
35
+ values: Values;
36
+ }
37
+ export interface SaveResult {
38
+ id: RecordId;
39
+ /** The record as stored, when the source recalculated anything. */
40
+ values?: Values;
41
+ }
42
+ export interface OnchangeRequest {
43
+ model: string;
44
+ id: RecordId | null;
45
+ /** The field that changed. */
46
+ changed: string;
47
+ values: Values;
48
+ }
49
+ export interface OnchangeResult {
50
+ /** New values for other fields. */
51
+ values?: Values;
52
+ /** Something to tell the person editing, without blocking them. */
53
+ warning?: string;
54
+ }
55
+ export interface SearchRequest {
56
+ /** The related model, from the field's `relation`. */
57
+ model: string;
58
+ query: string;
59
+ /** The field's filter, with every `valueFrom` already replaced by its value. */
60
+ filter?: ResolvedFilterCondition[];
61
+ limit?: number;
62
+ }
63
+ export type ResolvedFilterCondition = Omit<FilterCondition, 'valueFrom' | 'value'> & {
64
+ value: JsonValue;
65
+ };
66
+ export interface SubmitRequest {
67
+ pageId: string;
68
+ /** The answers to the questions that were shown. Skipped steps are left out. */
69
+ values: Values;
70
+ }
71
+ export interface SubmitResult {
72
+ id?: RecordId;
73
+ }
74
+ /**
75
+ * What changed, using the operation names Odoo gives its x2many commands, so
76
+ * an adapter maps them one to one.
77
+ */
78
+ export interface RecordChanges {
79
+ /** Changed values of every field that is not one2many or many2many. */
80
+ values: Values;
81
+ /** one2many changes, per field. */
82
+ lines: Record<string, LineOp[]>;
83
+ /** many2many changes, per field. */
84
+ links: Record<string, LinkOp[]>;
85
+ }
86
+ export type LineOp = {
87
+ op: 'create';
88
+ key: string;
89
+ values: Values;
90
+ } | {
91
+ op: 'update';
92
+ id: RecordId;
93
+ values: Values;
94
+ } | {
95
+ op: 'delete';
96
+ id: RecordId;
97
+ };
98
+ export type LinkOp = {
99
+ op: 'link';
100
+ id: RecordId;
101
+ } | {
102
+ op: 'unlink';
103
+ id: RecordId;
104
+ } | {
105
+ op: 'set';
106
+ ids: RecordId[];
107
+ } | {
108
+ op: 'clear';
109
+ };
@@ -0,0 +1,109 @@
1
+ import type { FilterCondition, Fields } from '../format/field';
2
+ import type { JsonValue } from '../format/json';
3
+ import type { RecordId, RelatedRecord, Values } from './values';
4
+ /**
5
+ * How Fieldia reaches data. Fieldia knows no backend: an app implements this
6
+ * interface for its own (a Flectra adapter, a REST client, a survey store),
7
+ * and every method is optional so a page uses only what it needs.
8
+ */
9
+ export interface DataSource {
10
+ /** Read a record. Needed to edit an existing record. */
11
+ load?(request: LoadRequest): Promise<Values>;
12
+ /** Create (`id: null`) or update a record. Needed to save a record page. */
13
+ save?(request: SaveRequest): Promise<SaveResult>;
14
+ /** Recalculate after a value changes, the way a backend's onchange does. */
15
+ onchange?(request: OnchangeRequest): Promise<OnchangeResult>;
16
+ /** Find records a many2one, many2many or reference may point to. */
17
+ search?(request: SearchRequest): Promise<RelatedRecord[]>;
18
+ /** Store one response to a `responses` page, such as a survey. */
19
+ submit?(request: SubmitRequest): Promise<SubmitResult>;
20
+ }
21
+ export interface LoadRequest {
22
+ model: string;
23
+ id: RecordId;
24
+ /** The page's fields, so the source reads exactly what the page shows. */
25
+ fields: Fields;
26
+ }
27
+ export interface SaveRequest {
28
+ model: string;
29
+ id: RecordId | null;
30
+ /** The page's fields, so the source knows each relation's model. */
31
+ fields: Fields;
32
+ /** Only what changed since the record was loaded or last saved. */
33
+ changes: RecordChanges;
34
+ /** Every value, for sources that save whole records. */
35
+ values: Values;
36
+ }
37
+ export interface SaveResult {
38
+ id: RecordId;
39
+ /** The record as stored, when the source recalculated anything. */
40
+ values?: Values;
41
+ }
42
+ export interface OnchangeRequest {
43
+ model: string;
44
+ id: RecordId | null;
45
+ /** The field that changed. */
46
+ changed: string;
47
+ values: Values;
48
+ }
49
+ export interface OnchangeResult {
50
+ /** New values for other fields. */
51
+ values?: Values;
52
+ /** Something to tell the person editing, without blocking them. */
53
+ warning?: string;
54
+ }
55
+ export interface SearchRequest {
56
+ /** The related model, from the field's `relation`. */
57
+ model: string;
58
+ query: string;
59
+ /** The field's filter, with every `valueFrom` already replaced by its value. */
60
+ filter?: ResolvedFilterCondition[];
61
+ limit?: number;
62
+ }
63
+ export type ResolvedFilterCondition = Omit<FilterCondition, 'valueFrom' | 'value'> & {
64
+ value: JsonValue;
65
+ };
66
+ export interface SubmitRequest {
67
+ pageId: string;
68
+ /** The answers to the questions that were shown. Skipped steps are left out. */
69
+ values: Values;
70
+ }
71
+ export interface SubmitResult {
72
+ id?: RecordId;
73
+ }
74
+ /**
75
+ * What changed, using the operation names Odoo gives its x2many commands, so
76
+ * an adapter maps them one to one.
77
+ */
78
+ export interface RecordChanges {
79
+ /** Changed values of every field that is not one2many or many2many. */
80
+ values: Values;
81
+ /** one2many changes, per field. */
82
+ lines: Record<string, LineOp[]>;
83
+ /** many2many changes, per field. */
84
+ links: Record<string, LinkOp[]>;
85
+ }
86
+ export type LineOp = {
87
+ op: 'create';
88
+ key: string;
89
+ values: Values;
90
+ } | {
91
+ op: 'update';
92
+ id: RecordId;
93
+ values: Values;
94
+ } | {
95
+ op: 'delete';
96
+ id: RecordId;
97
+ };
98
+ export type LinkOp = {
99
+ op: 'link';
100
+ id: RecordId;
101
+ } | {
102
+ op: 'unlink';
103
+ id: RecordId;
104
+ } | {
105
+ op: 'set';
106
+ ids: RecordId[];
107
+ } | {
108
+ op: 'clear';
109
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-source.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/data-source.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data-source.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-source.mjs","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/record/data-source.ts"],"names":[],"mappings":""}
@@ -0,0 +1,106 @@
1
+ import type { JsonValue } from '../format/json.mjs';
2
+ import type { Page } from '../format/page.mjs';
3
+ import { type Messages } from './messages.mjs';
4
+ import type { DataSource, RecordChanges } from './data-source.mjs';
5
+ import { type Scheduler } from './scheduler.mjs';
6
+ import { type RecordId, type RelatedRecord, type Value, type Values } from './values.mjs';
7
+ export type FormStatus = 'idle' | 'loading' | 'ready' | 'saving' | 'saved' | 'error';
8
+ export interface FormState {
9
+ readonly status: FormStatus;
10
+ readonly recordId: RecordId | null;
11
+ readonly values: Readonly<Values>;
12
+ /** Messages by field name; a line's field is `field.lineKey.subfield`. */
13
+ readonly errors: Readonly<Record<string, string>>;
14
+ /** Fields that differ from the record as loaded or last saved. */
15
+ readonly dirty: readonly string[];
16
+ /** A warning from the data source's onchange, shown without blocking. */
17
+ readonly warning: string | null;
18
+ /** Why loading or saving failed. */
19
+ readonly error: string | null;
20
+ /** A saved draft that can be restored. */
21
+ readonly draft: {
22
+ savedAt: string;
23
+ } | null;
24
+ /** The wizard step on screen, for a wizard page. */
25
+ readonly step: string | null;
26
+ }
27
+ /** What a layout element looks like right now. */
28
+ export interface NodeState {
29
+ invisible: boolean;
30
+ readonly: boolean;
31
+ required: boolean;
32
+ }
33
+ /** localStorage fits this, and so does anything else with the same three methods. */
34
+ export interface DraftStore {
35
+ getItem(key: string): string | null;
36
+ setItem(key: string, value: string): void;
37
+ removeItem(key: string): void;
38
+ }
39
+ export interface ActionRequest {
40
+ /** The button or stat button pressed. */
41
+ id: string;
42
+ action: string;
43
+ params?: {
44
+ [key: string]: JsonValue;
45
+ };
46
+ recordId: RecordId | null;
47
+ values: Values;
48
+ }
49
+ export interface FormOptions {
50
+ page: Page;
51
+ dataSource?: DataSource;
52
+ /** The record to edit. Leave out for a new record or a survey. */
53
+ recordId?: RecordId | null;
54
+ /** Values to start with, on top of each field's default. */
55
+ values?: Values;
56
+ /** What a button does. Fieldia hands the press over; the app decides. */
57
+ onAction?: (request: ActionRequest) => void | Promise<void>;
58
+ drafts?: {
59
+ store: DraftStore;
60
+ restore?: 'auto' | 'ask';
61
+ delayMs?: number;
62
+ };
63
+ autosave?: {
64
+ delayMs: number;
65
+ };
66
+ scheduler?: Scheduler;
67
+ /** Validation messages in the page's language. English by default. */
68
+ messages?: Messages;
69
+ }
70
+ export interface Form {
71
+ readonly page: Page;
72
+ getState(): FormState;
73
+ subscribe(listener: (state: FormState) => void): () => void;
74
+ load(): Promise<void>;
75
+ setValue(name: string, value: Value): void;
76
+ node(id: string): NodeState;
77
+ fieldReadonly(name: string): boolean;
78
+ validate(): boolean;
79
+ save(): Promise<boolean>;
80
+ reset(): void;
81
+ changes(): RecordChanges;
82
+ addLine(field: string, values?: Values): string;
83
+ updateLine(field: string, key: string, name: string, value: Value): void;
84
+ removeLine(field: string, key: string): void;
85
+ /** Records a many2one, many2many or reference may point to. A reference needs `options.model`. */
86
+ search(field: string, query: string, limit?: number, options?: {
87
+ model?: string;
88
+ }): Promise<RelatedRecord[]>;
89
+ /** The same, for a relation inside a one2many line, filtered by that line's values. */
90
+ searchLine(field: string, key: string, subfield: string, query: string, limit?: number): Promise<RelatedRecord[]>;
91
+ steps(): string[];
92
+ next(): boolean;
93
+ back(): boolean;
94
+ runAction(id: string): Promise<void>;
95
+ restoreDraft(): void;
96
+ discardDraft(): void;
97
+ /** Resolves once every onchange, save and autosave started so far has finished. */
98
+ settled(): Promise<void>;
99
+ dispose(): void;
100
+ }
101
+ /**
102
+ * The record state behind a page: values, what changed, what is visible and
103
+ * required, errors, loading and saving. No DOM and no framework — every
104
+ * binding renders from `getState()` and calls these methods.
105
+ */
106
+ export declare function createForm(options: FormOptions): Form;
@@ -0,0 +1,106 @@
1
+ import type { JsonValue } from '../format/json';
2
+ import type { Page } from '../format/page';
3
+ import { type Messages } from './messages';
4
+ import type { DataSource, RecordChanges } from './data-source';
5
+ import { type Scheduler } from './scheduler';
6
+ import { type RecordId, type RelatedRecord, type Value, type Values } from './values';
7
+ export type FormStatus = 'idle' | 'loading' | 'ready' | 'saving' | 'saved' | 'error';
8
+ export interface FormState {
9
+ readonly status: FormStatus;
10
+ readonly recordId: RecordId | null;
11
+ readonly values: Readonly<Values>;
12
+ /** Messages by field name; a line's field is `field.lineKey.subfield`. */
13
+ readonly errors: Readonly<Record<string, string>>;
14
+ /** Fields that differ from the record as loaded or last saved. */
15
+ readonly dirty: readonly string[];
16
+ /** A warning from the data source's onchange, shown without blocking. */
17
+ readonly warning: string | null;
18
+ /** Why loading or saving failed. */
19
+ readonly error: string | null;
20
+ /** A saved draft that can be restored. */
21
+ readonly draft: {
22
+ savedAt: string;
23
+ } | null;
24
+ /** The wizard step on screen, for a wizard page. */
25
+ readonly step: string | null;
26
+ }
27
+ /** What a layout element looks like right now. */
28
+ export interface NodeState {
29
+ invisible: boolean;
30
+ readonly: boolean;
31
+ required: boolean;
32
+ }
33
+ /** localStorage fits this, and so does anything else with the same three methods. */
34
+ export interface DraftStore {
35
+ getItem(key: string): string | null;
36
+ setItem(key: string, value: string): void;
37
+ removeItem(key: string): void;
38
+ }
39
+ export interface ActionRequest {
40
+ /** The button or stat button pressed. */
41
+ id: string;
42
+ action: string;
43
+ params?: {
44
+ [key: string]: JsonValue;
45
+ };
46
+ recordId: RecordId | null;
47
+ values: Values;
48
+ }
49
+ export interface FormOptions {
50
+ page: Page;
51
+ dataSource?: DataSource;
52
+ /** The record to edit. Leave out for a new record or a survey. */
53
+ recordId?: RecordId | null;
54
+ /** Values to start with, on top of each field's default. */
55
+ values?: Values;
56
+ /** What a button does. Fieldia hands the press over; the app decides. */
57
+ onAction?: (request: ActionRequest) => void | Promise<void>;
58
+ drafts?: {
59
+ store: DraftStore;
60
+ restore?: 'auto' | 'ask';
61
+ delayMs?: number;
62
+ };
63
+ autosave?: {
64
+ delayMs: number;
65
+ };
66
+ scheduler?: Scheduler;
67
+ /** Validation messages in the page's language. English by default. */
68
+ messages?: Messages;
69
+ }
70
+ export interface Form {
71
+ readonly page: Page;
72
+ getState(): FormState;
73
+ subscribe(listener: (state: FormState) => void): () => void;
74
+ load(): Promise<void>;
75
+ setValue(name: string, value: Value): void;
76
+ node(id: string): NodeState;
77
+ fieldReadonly(name: string): boolean;
78
+ validate(): boolean;
79
+ save(): Promise<boolean>;
80
+ reset(): void;
81
+ changes(): RecordChanges;
82
+ addLine(field: string, values?: Values): string;
83
+ updateLine(field: string, key: string, name: string, value: Value): void;
84
+ removeLine(field: string, key: string): void;
85
+ /** Records a many2one, many2many or reference may point to. A reference needs `options.model`. */
86
+ search(field: string, query: string, limit?: number, options?: {
87
+ model?: string;
88
+ }): Promise<RelatedRecord[]>;
89
+ /** The same, for a relation inside a one2many line, filtered by that line's values. */
90
+ searchLine(field: string, key: string, subfield: string, query: string, limit?: number): Promise<RelatedRecord[]>;
91
+ steps(): string[];
92
+ next(): boolean;
93
+ back(): boolean;
94
+ runAction(id: string): Promise<void>;
95
+ restoreDraft(): void;
96
+ discardDraft(): void;
97
+ /** Resolves once every onchange, save and autosave started so far has finished. */
98
+ settled(): Promise<void>;
99
+ dispose(): void;
100
+ }
101
+ /**
102
+ * The record state behind a page: values, what changed, what is visible and
103
+ * required, errors, loading and saving. No DOM and no framework — every
104
+ * binding renders from `getState()` and calls these methods.
105
+ */
106
+ export declare function createForm(options: FormOptions): Form;