@fieldia/core 0.6.0 → 0.7.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 (96) hide show
  1. package/package.json +1 -1
  2. package/schema/page.schema.json +55 -5
  3. package/src/index.d.mts +5 -14
  4. package/src/index.d.ts +5 -14
  5. package/src/index.js +4 -29
  6. package/src/index.js.map +1 -1
  7. package/src/index.mjs +4 -11
  8. package/src/index.mjs.map +1 -1
  9. package/src/lib/format/check-page.d.mts +9 -0
  10. package/src/lib/format/check-page.d.ts +9 -0
  11. package/src/lib/format/check-page.js +54 -0
  12. package/src/lib/format/check-page.js.map +1 -0
  13. package/src/lib/format/check-page.mjs +51 -0
  14. package/src/lib/format/check-page.mjs.map +1 -0
  15. package/src/lib/format/columns.d.mts +3 -0
  16. package/src/lib/format/columns.d.ts +3 -0
  17. package/src/lib/format/columns.js +8 -0
  18. package/src/lib/format/columns.js.map +1 -0
  19. package/src/lib/format/columns.mjs +5 -0
  20. package/src/lib/format/columns.mjs.map +1 -0
  21. package/src/lib/format/field.d.mts +163 -35
  22. package/src/lib/format/field.d.ts +163 -35
  23. package/src/lib/format/field.js +36 -38
  24. package/src/lib/format/field.js.map +1 -1
  25. package/src/lib/format/field.mjs +25 -29
  26. package/src/lib/format/field.mjs.map +1 -1
  27. package/src/lib/format/layout.d.mts +1 -2
  28. package/src/lib/format/layout.d.ts +1 -2
  29. package/src/lib/format/layout.js +3 -6
  30. package/src/lib/format/layout.js.map +1 -1
  31. package/src/lib/format/layout.mjs +1 -4
  32. package/src/lib/format/layout.mjs.map +1 -1
  33. package/src/lib/format/names.d.mts +5 -0
  34. package/src/lib/format/names.d.ts +5 -0
  35. package/src/lib/format/names.js +27 -0
  36. package/src/lib/format/names.js.map +1 -0
  37. package/src/lib/format/names.mjs +24 -0
  38. package/src/lib/format/names.mjs.map +1 -0
  39. package/src/lib/format/page.d.mts +46 -10
  40. package/src/lib/format/page.d.ts +46 -10
  41. package/src/lib/format/page.js +4 -3
  42. package/src/lib/format/page.js.map +1 -1
  43. package/src/lib/format/page.mjs +2 -2
  44. package/src/lib/format/page.mjs.map +1 -1
  45. package/src/lib/format/references.d.mts +35 -0
  46. package/src/lib/format/references.d.ts +35 -0
  47. package/src/lib/format/references.js +278 -0
  48. package/src/lib/format/references.js.map +1 -0
  49. package/src/lib/format/references.mjs +274 -0
  50. package/src/lib/format/references.mjs.map +1 -0
  51. package/src/lib/format/translate.d.mts +8 -0
  52. package/src/lib/format/translate.d.ts +8 -0
  53. package/src/lib/format/translate.js +36 -0
  54. package/src/lib/format/translate.js.map +1 -0
  55. package/src/lib/format/translate.mjs +33 -0
  56. package/src/lib/format/translate.mjs.map +1 -0
  57. package/src/lib/format/validate.d.mts +2 -13
  58. package/src/lib/format/validate.d.ts +2 -13
  59. package/src/lib/format/validate.js +2 -265
  60. package/src/lib/format/validate.js.map +1 -1
  61. package/src/lib/format/validate.mjs +1 -264
  62. package/src/lib/format/validate.mjs.map +1 -1
  63. package/src/lib/format/version.d.mts +2 -0
  64. package/src/lib/format/version.d.ts +2 -0
  65. package/src/lib/format/version.js +6 -0
  66. package/src/lib/format/version.js.map +1 -0
  67. package/src/lib/format/version.mjs +3 -0
  68. package/src/lib/format/version.mjs.map +1 -0
  69. package/src/lib/record/data-source.d.mts +27 -1
  70. package/src/lib/record/data-source.d.ts +27 -1
  71. package/src/lib/record/data-source.js +16 -0
  72. package/src/lib/record/data-source.js.map +1 -1
  73. package/src/lib/record/data-source.mjs +14 -1
  74. package/src/lib/record/data-source.mjs.map +1 -1
  75. package/src/lib/record/filter.d.mts +8 -0
  76. package/src/lib/record/filter.d.ts +8 -0
  77. package/src/lib/record/filter.js +66 -0
  78. package/src/lib/record/filter.js.map +1 -0
  79. package/src/lib/record/filter.mjs +63 -0
  80. package/src/lib/record/filter.mjs.map +1 -0
  81. package/src/lib/record/form.d.mts +5 -1
  82. package/src/lib/record/form.d.ts +5 -1
  83. package/src/lib/record/form.js +33 -10
  84. package/src/lib/record/form.js.map +1 -1
  85. package/src/lib/record/form.mjs +33 -10
  86. package/src/lib/record/form.mjs.map +1 -1
  87. package/src/lib/record/memory-data-source.js +2 -28
  88. package/src/lib/record/memory-data-source.js.map +1 -1
  89. package/src/lib/record/memory-data-source.mjs +2 -28
  90. package/src/lib/record/memory-data-source.mjs.map +1 -1
  91. package/src/runtime.d.mts +26 -0
  92. package/src/runtime.d.ts +26 -0
  93. package/src/runtime.js +44 -0
  94. package/src/runtime.js.map +1 -0
  95. package/src/runtime.mjs +16 -0
  96. package/src/runtime.mjs.map +1 -0
@@ -0,0 +1,274 @@
1
+ import { compileModifier } from '../expression/modifier.mjs';
2
+ const has = (record, key) => Object.prototype.hasOwnProperty.call(record, key);
3
+ /** The second pass of every check: ids unique, every name defined, every condition readable. */
4
+ export class ReferenceCheck {
5
+ page;
6
+ issues = [];
7
+ ids = new Map();
8
+ constructor(page) {
9
+ this.page = page;
10
+ }
11
+ run() {
12
+ this.checkFields(this.page.fields, 'fields');
13
+ this.walkRoot(this.page.layout, 'layout');
14
+ return this.issues;
15
+ }
16
+ report(path, message) {
17
+ this.issues.push({ path, message });
18
+ }
19
+ claim(id, path) {
20
+ const first = this.ids.get(id);
21
+ if (first !== undefined)
22
+ this.report(path, `duplicate id "${id}", also used at ${first}`);
23
+ else
24
+ this.ids.set(id, path);
25
+ }
26
+ /** The field a reference names, or a reported issue and undefined. */
27
+ need(name, path, scope = this.page.fields) {
28
+ if (has(scope, name))
29
+ return scope[name];
30
+ this.report(path, `no field "${name}"`);
31
+ return undefined;
32
+ }
33
+ /** Every modifier on `owner` must read, and read only fields of this page. */
34
+ checkModifiers(owner, path, keys = ['invisible']) {
35
+ for (const key of keys) {
36
+ const value = owner[key];
37
+ if (typeof value !== 'string')
38
+ continue;
39
+ let fields;
40
+ try {
41
+ fields = compileModifier(value).fields;
42
+ }
43
+ catch (error) {
44
+ this.report(`${path}.${key}`, `cannot read "${value}": ${error.message}`);
45
+ continue;
46
+ }
47
+ for (const name of fields) {
48
+ if (!has(this.page.fields, name)) {
49
+ this.report(`${path}.${key}`, `"${value}" reads "${name}", which is not a field of this page`);
50
+ }
51
+ }
52
+ }
53
+ }
54
+ checkFields(fields, base) {
55
+ for (const [name, def] of Object.entries(fields)) {
56
+ const path = `${base}.${name}`;
57
+ if (def.type === 'monetary' && def.currencyField !== undefined) {
58
+ const currency = this.need(def.currencyField, `${path}.currencyField`, fields);
59
+ if (currency && !['many2one', 'selection', 'char'].includes(currency.type)) {
60
+ this.report(`${path}.currencyField`, `"${def.currencyField}" is a ${currency.type}; a currency field must be a many2one, selection or char`);
61
+ }
62
+ }
63
+ if ((def.type === 'many2one' || def.type === 'many2many') && def.filter) {
64
+ // Groups nest: each valueFrom inside them must name a field too.
65
+ const walk = (item, at) => {
66
+ if ('any' in item)
67
+ return item.any.forEach((inner, i) => walk(inner, `${at}.any[${i}]`));
68
+ if ('all' in item)
69
+ return item.all.forEach((inner, i) => walk(inner, `${at}.all[${i}]`));
70
+ if (item.valueFrom !== undefined)
71
+ this.need(item.valueFrom, `${at}.valueFrom`, fields);
72
+ };
73
+ def.filter.forEach((item, i) => {
74
+ walk(item, `${path}.filter[${i}]`);
75
+ });
76
+ }
77
+ if (def.type === 'properties' && def.definitions) {
78
+ const seen = new Set();
79
+ def.definitions.forEach((property, i) => {
80
+ if (property.type === 'selection' && !property.options) {
81
+ this.report(`${path}.definitions[${i}].options`, 'a choice property needs its choices');
82
+ }
83
+ if (seen.has(property.name))
84
+ this.report(`${path}.definitions[${i}].name`, `"${property.name}" is named twice`);
85
+ seen.add(property.name);
86
+ });
87
+ }
88
+ if (def.type === 'one2many') {
89
+ this.checkFields(def.fields, `${path}.fields`);
90
+ if (def.lineKinds)
91
+ this.checkLineKinds(name, def.lineKinds, def.fields, `${path}.lineKinds`);
92
+ if (def.sequenceField !== undefined) {
93
+ const sequence = def.fields[def.sequenceField];
94
+ if (!sequence)
95
+ this.report(`${path}.sequenceField`, `"${def.sequenceField}" is not a field of the lines of "${name}"`);
96
+ else if (sequence.type !== 'integer') {
97
+ this.report(`${path}.sequenceField`, `"${def.sequenceField}" is a ${sequence.type}; the field that keeps the order of lines must be an integer`);
98
+ }
99
+ }
100
+ }
101
+ }
102
+ }
103
+ checkLineKinds(field, kinds, lineFields, path) {
104
+ const kindField = lineFields[kinds.field];
105
+ if (!kindField)
106
+ this.report(`${path}.field`, `"${kinds.field}" is not a field of the lines of "${field}"`);
107
+ else if (kindField.type !== 'selection' && kindField.type !== 'char') {
108
+ this.report(`${path}.field`, `"${kinds.field}" is a ${kindField.type}; the field that says what a line is must be a selection or char`);
109
+ }
110
+ else if (kindField.type === 'selection') {
111
+ for (const which of ['section', 'note']) {
112
+ const value = kinds[which] ?? which;
113
+ if (!kindField.options.some((o) => o.value === value))
114
+ this.report(`${path}.${which}`, `"${kinds.field}" has no option "${value}"`);
115
+ }
116
+ }
117
+ const text = lineFields[kinds.text];
118
+ if (!text)
119
+ this.report(`${path}.text`, `"${kinds.text}" is not a field of the lines of "${field}"`);
120
+ else if (text.type !== 'char' && text.type !== 'text') {
121
+ this.report(`${path}.text`, `"${kinds.text}" is a ${text.type}; a section's or note's text must be a char or text field`);
122
+ }
123
+ }
124
+ walkRoot(root, path) {
125
+ if (root.type === 'tabs')
126
+ return this.walkNode(root, path);
127
+ this.claim(root.id, path);
128
+ if (root.type === 'sheet')
129
+ return this.walkSheet(root, path);
130
+ if (root.type === 'sections')
131
+ return this.walkChildren(root.children, path);
132
+ root.children.forEach((step, i) => {
133
+ const stepPath = `${path}.children[${i}]`;
134
+ this.claim(step.id, stepPath);
135
+ this.checkModifiers(step, stepPath);
136
+ this.walkChildren(step.children, stepPath);
137
+ });
138
+ }
139
+ walkChildren(children, path) {
140
+ children.forEach((child, i) => this.walkNode(child, `${path}.children[${i}]`));
141
+ }
142
+ walkNode(node, path) {
143
+ this.claim(node.id, path);
144
+ this.checkModifiers(node, path, node.type === 'field' ? ['invisible', 'readonly', 'required'] : node.type === 'section' ? ['invisible', 'readonly'] : ['invisible']);
145
+ switch (node.type) {
146
+ case 'field':
147
+ return this.checkFieldNode(node, path);
148
+ case 'section':
149
+ if (node.collapsible && !node.title)
150
+ this.report(path, 'a collapsible section needs a title to fold it by');
151
+ if (node.collapsed && !node.collapsible)
152
+ this.report(path, 'collapsed needs collapsible: true');
153
+ return this.walkChildren(node.children, path);
154
+ case 'tabs':
155
+ return this.walkTabs(node, path);
156
+ default:
157
+ return;
158
+ }
159
+ }
160
+ walkTabs(node, path) {
161
+ node.children.forEach((tab, i) => {
162
+ const tabPath = `${path}.children[${i}]`;
163
+ this.claim(tab.id, tabPath);
164
+ this.checkModifiers(tab, tabPath);
165
+ this.walkChildren(tab.children, tabPath);
166
+ });
167
+ }
168
+ walkSheet(sheet, path) {
169
+ if (sheet.title) {
170
+ this.need(sheet.title.field, `${path}.title.field`);
171
+ if (sheet.title.subtitleField !== undefined)
172
+ this.need(sheet.title.subtitleField, `${path}.title.subtitleField`);
173
+ if (sheet.title.avatarField !== undefined)
174
+ this.need(sheet.title.avatarField, `${path}.title.avatarField`);
175
+ }
176
+ if (sheet.statusbar) {
177
+ const { field, visibleStates } = sheet.statusbar;
178
+ const def = this.need(field, `${path}.statusbar.field`);
179
+ if (def && def.type !== 'selection' && def.type !== 'many2one') {
180
+ this.report(`${path}.statusbar.field`, `"${field}" is a ${def.type}; a statusbar needs a selection or many2one`);
181
+ }
182
+ if (def?.type === 'selection' && visibleStates) {
183
+ const values = new Set(def.options.map((o) => o.value));
184
+ visibleStates.forEach((state, i) => {
185
+ if (!values.has(state)) {
186
+ this.report(`${path}.statusbar.visibleStates[${i}]`, `"${state}" is not an option of "${field}"`);
187
+ }
188
+ });
189
+ }
190
+ }
191
+ sheet.buttons?.forEach((button, i) => {
192
+ this.claim(button.id, `${path}.buttons[${i}]`);
193
+ this.checkModifiers(button, `${path}.buttons[${i}]`);
194
+ });
195
+ sheet.statButtons?.forEach((stat, i) => {
196
+ this.claim(stat.id, `${path}.statButtons[${i}]`);
197
+ this.checkModifiers(stat, `${path}.statButtons[${i}]`);
198
+ if (stat.field !== undefined)
199
+ this.need(stat.field, `${path}.statButtons[${i}].field`);
200
+ });
201
+ if (sheet.ribbon) {
202
+ this.claim(sheet.ribbon.id, `${path}.ribbon`);
203
+ this.checkModifiers(sheet.ribbon, `${path}.ribbon`);
204
+ }
205
+ sheet.badges?.forEach((badge, i) => {
206
+ this.claim(badge.id, `${path}.badges[${i}]`);
207
+ this.checkModifiers(badge, `${path}.badges[${i}]`);
208
+ });
209
+ for (const place of ['above', 'below']) {
210
+ sheet.title?.[place]?.forEach((node, i) => this.walkNode(node, `${path}.title.${place}[${i}]`));
211
+ }
212
+ sheet.alerts?.forEach((alert, i) => {
213
+ this.claim(alert.id, `${path}.alerts[${i}]`);
214
+ this.checkModifiers(alert, `${path}.alerts[${i}]`);
215
+ });
216
+ this.walkChildren(sheet.children, path);
217
+ if (sheet.sidePanel) {
218
+ this.claim(sheet.sidePanel.id, `${path}.sidePanel`);
219
+ this.checkModifiers(sheet.sidePanel, `${path}.sidePanel`);
220
+ }
221
+ }
222
+ checkFieldNode(node, path) {
223
+ const def = this.need(node.field, `${path}.field`);
224
+ if (def && node.totals) {
225
+ if (def.type !== 'one2many') {
226
+ this.report(`${path}.totals`, `totals only apply to one2many fields; "${node.field}" is a ${def.type}`);
227
+ }
228
+ else {
229
+ node.totals.forEach((column, i) => {
230
+ const sub = has(def.fields, column) ? def.fields[column] : undefined;
231
+ if (!sub)
232
+ this.report(`${path}.totals[${i}]`, `"${column}" is not a field of the lines of "${node.field}"`);
233
+ else if (!['integer', 'float', 'monetary'].includes(sub.type)) {
234
+ this.report(`${path}.totals[${i}]`, `"${column}" is a ${sub.type}; only integer, float and monetary columns add up`);
235
+ }
236
+ });
237
+ }
238
+ }
239
+ // Options that point at another field: by convention their names end in "Field".
240
+ for (const [key, value] of Object.entries(node.options ?? {})) {
241
+ if (key.endsWith('Field') && typeof value === 'string')
242
+ this.need(value, `${path}.options.${key}`);
243
+ }
244
+ if (def && node.editMode && def.type !== 'one2many') {
245
+ this.report(`${path}.editMode`, `editMode only applies to one2many fields; "${node.field}" is a ${def.type}`);
246
+ }
247
+ if (def && node.optionalColumns) {
248
+ if (def.type !== 'one2many') {
249
+ this.report(`${path}.optionalColumns`, `optional columns only apply to one2many fields; "${node.field}" is a ${def.type}`);
250
+ }
251
+ else {
252
+ // The columns the table shows: those named, or every line field but the structural ones.
253
+ const shown = node.columns ?? Object.keys(def.fields).filter((c) => c !== def.lineKinds?.field && c !== def.sequenceField);
254
+ for (const column of Object.keys(node.optionalColumns)) {
255
+ if (!shown.includes(column))
256
+ this.report(`${path}.optionalColumns.${column}`, `"${column}" is not a column of "${node.field}"`);
257
+ }
258
+ }
259
+ }
260
+ if (!def || !node.columns)
261
+ return;
262
+ if (def.type === 'one2many') {
263
+ node.columns.forEach((column, i) => {
264
+ if (!has(def.fields, column)) {
265
+ this.report(`${path}.columns[${i}]`, `"${column}" is not a field of the lines of "${node.field}"`);
266
+ }
267
+ });
268
+ }
269
+ else if (def.type !== 'many2many') {
270
+ this.report(`${path}.columns`, `columns only apply to one2many and many2many fields; "${node.field}" is a ${def.type}`);
271
+ }
272
+ }
273
+ }
274
+ //# sourceMappingURL=references.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"references.mjs","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/format/references.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { Page } from './page.mjs';
2
+ /**
3
+ * The page with every word a person reads passed through the app's own
4
+ * translator, for apps that keep their translations by text or by key. Ids,
5
+ * field names, choice values, conditions and data stay as they are; the page
6
+ * given is left alone.
7
+ */
8
+ export declare function translatePage(page: Page, translate: (text: string) => string): Page;
@@ -0,0 +1,8 @@
1
+ import type { Page } from './page';
2
+ /**
3
+ * The page with every word a person reads passed through the app's own
4
+ * translator, for apps that keep their translations by text or by key. Ids,
5
+ * field names, choice values, conditions and data stay as they are; the page
6
+ * given is left alone.
7
+ */
8
+ export declare function translatePage(page: Page, translate: (text: string) => string): Page;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.translatePage = translatePage;
4
+ /** Keys whose text a person reads: titles, labels, help, prompts, messages and a wizard's buttons. */
5
+ const TEXT_KEYS = new Set(['title', 'description', 'label', 'help', 'placeholder', 'message', 'text', 'confirm', 'nextLabel', 'backLabel', 'finishLabel']);
6
+ /**
7
+ * Parts that hold names or data, never words to translate: which line fields
8
+ * mark sections and notes, a link's filter, a default value, a widget's options,
9
+ * and what the page's data is.
10
+ */
11
+ const NOT_TEXT = new Set(['lineKinds', 'filter', 'default', 'data']);
12
+ /**
13
+ * The page with every word a person reads passed through the app's own
14
+ * translator, for apps that keep their translations by text or by key. Ids,
15
+ * field names, choice values, conditions and data stay as they are; the page
16
+ * given is left alone.
17
+ */
18
+ function translatePage(page, translate) {
19
+ const walk = (value, key) => {
20
+ if (typeof value === 'string')
21
+ return key !== null && TEXT_KEYS.has(key) ? translate(value) : value;
22
+ if (Array.isArray(value))
23
+ return value.map((item) => walk(item, null));
24
+ if (value === null || typeof value !== 'object')
25
+ return value;
26
+ const out = {};
27
+ for (const [name, inner] of Object.entries(value)) {
28
+ // A field node's `options` are its widget's settings, not a list of choices.
29
+ const widgetOptions = name === 'options' && !Array.isArray(inner);
30
+ out[name] = NOT_TEXT.has(name) || widgetOptions ? inner : walk(inner, name);
31
+ }
32
+ return out;
33
+ };
34
+ return walk(page, null);
35
+ }
36
+ //# sourceMappingURL=translate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translate.js","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/format/translate.ts"],"names":[],"mappings":";;AAkBA,sCAcC;AA9BD,sGAAsG;AACtG,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;AAE3J;;;;GAIG;AACH,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;AAErE;;;;;GAKG;AACH,SAAgB,aAAa,CAAC,IAAU,EAAE,SAAmC;IAC3E,MAAM,IAAI,GAAG,CAAC,KAAc,EAAE,GAAkB,EAAW,EAAE;QAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,GAAG,KAAK,IAAI,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACpG,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QACvE,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC9D,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAClD,6EAA6E;YAC7E,MAAM,aAAa,GAAG,IAAI,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAClE,GAAG,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC9E,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;IACF,OAAO,IAAI,CAAC,IAAI,EAAE,IAAI,CAAS,CAAC;AAClC,CAAC"}
@@ -0,0 +1,33 @@
1
+ /** Keys whose text a person reads: titles, labels, help, prompts, messages and a wizard's buttons. */
2
+ const TEXT_KEYS = new Set(['title', 'description', 'label', 'help', 'placeholder', 'message', 'text', 'confirm', 'nextLabel', 'backLabel', 'finishLabel']);
3
+ /**
4
+ * Parts that hold names or data, never words to translate: which line fields
5
+ * mark sections and notes, a link's filter, a default value, a widget's options,
6
+ * and what the page's data is.
7
+ */
8
+ const NOT_TEXT = new Set(['lineKinds', 'filter', 'default', 'data']);
9
+ /**
10
+ * The page with every word a person reads passed through the app's own
11
+ * translator, for apps that keep their translations by text or by key. Ids,
12
+ * field names, choice values, conditions and data stay as they are; the page
13
+ * given is left alone.
14
+ */
15
+ export function translatePage(page, translate) {
16
+ const walk = (value, key) => {
17
+ if (typeof value === 'string')
18
+ return key !== null && TEXT_KEYS.has(key) ? translate(value) : value;
19
+ if (Array.isArray(value))
20
+ return value.map((item) => walk(item, null));
21
+ if (value === null || typeof value !== 'object')
22
+ return value;
23
+ const out = {};
24
+ for (const [name, inner] of Object.entries(value)) {
25
+ // A field node's `options` are its widget's settings, not a list of choices.
26
+ const widgetOptions = name === 'options' && !Array.isArray(inner);
27
+ out[name] = NOT_TEXT.has(name) || widgetOptions ? inner : walk(inner, name);
28
+ }
29
+ return out;
30
+ };
31
+ return walk(page, null);
32
+ }
33
+ //# sourceMappingURL=translate.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translate.mjs","sourceRoot":"","sources":["../../../../../../libs/core/src/lib/format/translate.ts"],"names":[],"mappings":"AAEA,sGAAsG;AACtG,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;AAE3J;;;;GAIG;AACH,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;AAErE;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAU,EAAE,SAAmC;IAC3E,MAAM,IAAI,GAAG,CAAC,KAAc,EAAE,GAAkB,EAAW,EAAE;QAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,GAAG,KAAK,IAAI,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACpG,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QACvE,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC9D,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAClD,6EAA6E;YAC7E,MAAM,aAAa,GAAG,IAAI,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAClE,GAAG,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC9E,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;IACF,OAAO,IAAI,CAAC,IAAI,EAAE,IAAI,CAAS,CAAC;AAClC,CAAC"}
@@ -1,16 +1,5 @@
1
- import { type Page } from './page.mjs';
2
- export interface PageIssue {
3
- /** Where the problem is, as a path into the page: `layout.children[0].field`. */
4
- path: string;
5
- message: string;
6
- }
7
- export type PageValidation = {
8
- ok: true;
9
- page: Page;
10
- } | {
11
- ok: false;
12
- issues: PageIssue[];
13
- };
1
+ import { type PageValidation } from './references.mjs';
2
+ export type { PageIssue, PageValidation } from './references.mjs';
14
3
  /**
15
4
  * Check a page in two passes: its shape against the format, then every
16
5
  * reference inside it — ids unique, every field a layout, title, statusbar,
@@ -1,16 +1,5 @@
1
- import { type Page } from './page';
2
- export interface PageIssue {
3
- /** Where the problem is, as a path into the page: `layout.children[0].field`. */
4
- path: string;
5
- message: string;
6
- }
7
- export type PageValidation = {
8
- ok: true;
9
- page: Page;
10
- } | {
11
- ok: false;
12
- issues: PageIssue[];
13
- };
1
+ import { type PageValidation } from './references';
2
+ export type { PageIssue, PageValidation } from './references';
14
3
  /**
15
4
  * Check a page in two passes: its shape against the format, then every
16
5
  * reference inside it — ids unique, every field a layout, title, statusbar,