@dforge-core/metadata 0.0.50 → 0.0.51
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/CHANGELOG.md +8 -0
- package/dist/dsl/index.js +8 -2
- package/dist/dsl/index.js.map +1 -1
- package/dist/index.d.ts +23 -3
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/schemas/data_views.schema.json +54 -1
- package/schemas/entity.schema.json +19 -0
- package/src/data-views.ts +24 -0
- package/src/dsl/builtins.ts +8 -2
- package/src/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dforge-core/metadata",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.51",
|
|
4
4
|
"description": "Canonical dForge authoring registries — field types, base datatypes, column types, traits, data-view kinds and chart types — with derivation helpers. Runtime-dependency-free; the single source of truth shared by editors, the web app and the CLI.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "dForge",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"properties": {
|
|
15
15
|
"viewType": {
|
|
16
16
|
"type": "string",
|
|
17
|
-
"enum": ["grid", "list", "kanban", "calendar", "gallery", "tree-grid", "diagram", "library", "matrix"],
|
|
17
|
+
"enum": ["grid", "list", "checklist", "kanban", "calendar", "gallery", "tree-grid", "diagram", "library", "matrix"],
|
|
18
18
|
"default": "grid",
|
|
19
19
|
"description": "View display type. Optional — omitted or unknown values fall back to 'grid' at runtime."
|
|
20
20
|
},
|
|
@@ -118,6 +118,18 @@
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
},
|
|
121
|
+
"checklist": {
|
|
122
|
+
"if": {
|
|
123
|
+
"properties": { "viewType": { "const": "checklist" } },
|
|
124
|
+
"required": ["viewType"]
|
|
125
|
+
},
|
|
126
|
+
"then": {
|
|
127
|
+
"properties": {
|
|
128
|
+
"viewConfig": { "$ref": "#/$defs/checklistViewConfig" }
|
|
129
|
+
},
|
|
130
|
+
"required": ["viewConfig"]
|
|
131
|
+
}
|
|
132
|
+
},
|
|
121
133
|
"diagram": {
|
|
122
134
|
"if": {
|
|
123
135
|
"properties": { "viewType": { "const": "diagram" } },
|
|
@@ -249,6 +261,47 @@
|
|
|
249
261
|
},
|
|
250
262
|
"additionalProperties": false
|
|
251
263
|
},
|
|
264
|
+
"checklistViewConfig": {
|
|
265
|
+
"type": "object",
|
|
266
|
+
"required": ["doneField"],
|
|
267
|
+
"properties": {
|
|
268
|
+
"titleField": {
|
|
269
|
+
"type": "string",
|
|
270
|
+
"description": "Column code of the row title; defaults to the record's display name. Also the column an inline add row types into"
|
|
271
|
+
},
|
|
272
|
+
"doneField": {
|
|
273
|
+
"type": "string",
|
|
274
|
+
"description": "Column the row's done circle reads and writes: a bool column, or a dropdown column with doneValue"
|
|
275
|
+
},
|
|
276
|
+
"doneValue": {
|
|
277
|
+
"type": "string",
|
|
278
|
+
"description": "Option value of a dropdown doneField that means done (ignored for a bool doneField)"
|
|
279
|
+
},
|
|
280
|
+
"undoneValue": {
|
|
281
|
+
"type": "string",
|
|
282
|
+
"description": "Option value a dropdown doneField is set back to when the circle is cleared (ignored for a bool doneField)"
|
|
283
|
+
},
|
|
284
|
+
"groupByField": {
|
|
285
|
+
"type": "string",
|
|
286
|
+
"description": "Dropdown, reference or user column the rows are grouped by"
|
|
287
|
+
},
|
|
288
|
+
"groupByOptions": {
|
|
289
|
+
"type": "array",
|
|
290
|
+
"items": { "type": "string" },
|
|
291
|
+
"description": "Columns the user may regroup by; must include groupByField"
|
|
292
|
+
},
|
|
293
|
+
"collapsedGroups": {
|
|
294
|
+
"type": "array",
|
|
295
|
+
"items": { "type": "string" },
|
|
296
|
+
"description": "Option values of groupByField whose groups start collapsed"
|
|
297
|
+
},
|
|
298
|
+
"inlineAdd": {
|
|
299
|
+
"type": "boolean",
|
|
300
|
+
"description": "Show an add row in each group (at the top when ungrouped)"
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
"additionalProperties": false
|
|
304
|
+
},
|
|
252
305
|
"listLevelConfig": {
|
|
253
306
|
"type": "object",
|
|
254
307
|
"required": ["entityCode", "foreignKey"],
|
|
@@ -602,6 +602,25 @@
|
|
|
602
602
|
"type": "string",
|
|
603
603
|
"description": "Format rule for this column, as an ECMAScript regex source. Overrides the field type's own pattern (field_type.def_params.pattern, which is what makes email/phone/url reject a malformed value). Enforced in the browser and again on data.insert / data.update, so keep to constructs both engines read alike: [0-9] and \\d are the same there, \\s is normalized to JavaScript's set, and a pattern that will not compile is skipped by both rather than enforced by one."
|
|
604
604
|
},
|
|
605
|
+
"fieldOptions": {
|
|
606
|
+
"type": "object",
|
|
607
|
+
"description": "Per-record rules for this field, each a formula over the record evaluated in the browser wherever the value renders (grid, card, list, checklist, kanban). $value stands for this column, so one rule (e.g. on a column domain) fits every column using it: IF($value < 0, 'danger', ''). Install refuses a rule that does not parse or calls an unknown function. Not-equal is != (there is no <>).",
|
|
608
|
+
"properties": {
|
|
609
|
+
"foreColor": {
|
|
610
|
+
"type": "string",
|
|
611
|
+
"description": "Formula returning the text colour, or '' for none. A theme name (danger, warning, success, info, accent, muted) follows light/dark mode and the UI style; any other value is used as CSS. E.g. IF([due_date] < TODAY() AND [status] != 'done', 'danger', '')"
|
|
612
|
+
},
|
|
613
|
+
"backColor": {
|
|
614
|
+
"type": "string",
|
|
615
|
+
"description": "Formula returning the background colour, or '' for none. A theme name gives that colour's subtle tint."
|
|
616
|
+
},
|
|
617
|
+
"canEdit": {
|
|
618
|
+
"type": "string",
|
|
619
|
+
"description": "Formula; false makes the field read-only on that record (a UI hint — the server enforces its own locks)."
|
|
620
|
+
}
|
|
621
|
+
},
|
|
622
|
+
"additionalProperties": false
|
|
623
|
+
},
|
|
605
624
|
"patternFlags": {
|
|
606
625
|
"type": "string",
|
|
607
626
|
"description": "Flags for 'pattern', as a JavaScript regex literal would carry them; 'i' and 'm' are the two honoured, each at most once — the RegExp constructor rejects a repeated flag, and a rule the browser cannot compile is skipped there and would then be enforced by the API alone. JavaScript has no inline (?i), so case-insensitivity has to be stated here.",
|
package/src/data-views.ts
CHANGED
|
@@ -12,6 +12,7 @@ export type { NamedKind };
|
|
|
12
12
|
export type ViewType =
|
|
13
13
|
| "grid"
|
|
14
14
|
| "list"
|
|
15
|
+
| "checklist"
|
|
15
16
|
| "kanban"
|
|
16
17
|
| "calendar"
|
|
17
18
|
| "gallery"
|
|
@@ -24,6 +25,7 @@ export type ViewType =
|
|
|
24
25
|
export const dataViewKinds: readonly NamedKind[] = [
|
|
25
26
|
{ cd: "grid", name: "Grid" },
|
|
26
27
|
{ cd: "list", name: "List" },
|
|
28
|
+
{ cd: "checklist", name: "Checklist" },
|
|
27
29
|
{ cd: "kanban", name: "Kanban" },
|
|
28
30
|
{ cd: "calendar", name: "Calendar" },
|
|
29
31
|
{ cd: "gallery", name: "Gallery" },
|
|
@@ -121,6 +123,27 @@ export interface ListViewConfig {
|
|
|
121
123
|
inlineAdd?: boolean;
|
|
122
124
|
}
|
|
123
125
|
|
|
126
|
+
export interface ChecklistViewConfig {
|
|
127
|
+
/** Column of the row title; defaults to the record's display name. Also
|
|
128
|
+
* the column an inline add row types into. */
|
|
129
|
+
titleField?: string;
|
|
130
|
+
/** Column the row's done circle reads and writes: a bool column, or a
|
|
131
|
+
* dropdown column together with `doneValue`. */
|
|
132
|
+
doneField: string;
|
|
133
|
+
/** Option value of a dropdown `doneField` that means done. */
|
|
134
|
+
doneValue?: string;
|
|
135
|
+
/** Option value a dropdown `doneField` is set back to when the circle is cleared. */
|
|
136
|
+
undoneValue?: string;
|
|
137
|
+
/** Dropdown, reference or user column the rows are grouped by. */
|
|
138
|
+
groupByField?: string;
|
|
139
|
+
/** Columns the user may regroup by; includes `groupByField`. */
|
|
140
|
+
groupByOptions?: string[];
|
|
141
|
+
/** Option values of `groupByField` whose groups start collapsed. */
|
|
142
|
+
collapsedGroups?: string[];
|
|
143
|
+
/** Show an add row in each group (at the top when ungrouped). */
|
|
144
|
+
inlineAdd?: boolean;
|
|
145
|
+
}
|
|
146
|
+
|
|
124
147
|
export interface DiagramViewConfig {
|
|
125
148
|
/** Column to group diagram nodes by. */
|
|
126
149
|
groupByField?: string;
|
|
@@ -149,6 +172,7 @@ export interface DataViewDef {
|
|
|
149
172
|
| CalendarViewConfig
|
|
150
173
|
| TreeGridViewConfig
|
|
151
174
|
| ListViewConfig
|
|
175
|
+
| ChecklistViewConfig
|
|
152
176
|
| DiagramViewConfig
|
|
153
177
|
| Record<string, unknown>;
|
|
154
178
|
}
|
package/src/dsl/builtins.ts
CHANGED
|
@@ -149,9 +149,9 @@ export const BUILTINS: Builtin[] = [
|
|
|
149
149
|
},
|
|
150
150
|
{
|
|
151
151
|
name: "sendEmail",
|
|
152
|
-
signature: "sendEmail(to, subjectOrTemplate, dataOrBody?, attachments?)",
|
|
152
|
+
signature: "sendEmail(to, subjectOrTemplate, dataOrBody?, attachments?, options?)",
|
|
153
153
|
returns: "void",
|
|
154
|
-
doc: "Queue an outbound email. Three arguments, and the **second** picks the mode: `sendEmail(to, 'order.shipped', { ref: [code] })` sends a template, `sendEmail(to, 'Your order shipped', '<p>…</p>')` sends raw HTML. A second argument with no spaces that contains `.` or `_` is read as a template code — so a raw subject like `'Shipped.'` silently becomes one; give a raw subject spaces. The optional **fourth** argument attaches files: a `printPdf()`, `attachText()` or `attachBase64()` result, or an array of them (`[a, b]`; pass a single file as itself, because a one-name `[a]` reads as a field reference in the DSL). A `printPdf()` file can be attached only by the user who generated it (or a workspace admin) and not in a scheduled job; a file built with `attachText()` / `attachBase64()` has no owner and works everywhere, a scheduled job included. At most 5 files and 10 MB in all per email (`Email:MaxAttachments`, `Email:MaxAttachmentBytes`). A file the sender may not attach fails the action.",
|
|
154
|
+
doc: "Queue an outbound email. Three arguments, and the **second** picks the mode: `sendEmail(to, 'order.shipped', { ref: [code] })` sends a template, `sendEmail(to, 'Your order shipped', '<p>…</p>')` sends raw HTML. A second argument with no spaces that contains `.` or `_` is read as a template code — so a raw subject like `'Shipped.'` silently becomes one; give a raw subject spaces. The optional **fourth** argument attaches files: a `printPdf()`, `attachText()` or `attachBase64()` result, or an array of them (`[a, b]`; pass a single file as itself, because a one-name `[a]` reads as a field reference in the DSL). A `printPdf()` file can be attached only by the user who generated it (or a workspace admin) and not in a scheduled job; a file built with `attachText()` / `attachBase64()` has no owner and works everywhere, a scheduled job included. At most 5 files and 10 MB in all per email (`Email:MaxAttachments`, `Email:MaxAttachmentBytes`). A file the sender may not attach fails the action. The optional **fifth** argument sets threading headers so a reply finds this mail: `{ messageId, inReplyTo, references, replyTo }` (ids with angle brackets, `references` an array; pass `null` as the fourth argument when there are no files). Every key is optional; an unknown key, a malformed id (strictly `<word.word@word.word>`) or address, or a line break fails the action by name.",
|
|
155
155
|
},
|
|
156
156
|
|
|
157
157
|
// External calls
|
|
@@ -161,6 +161,12 @@ export const BUILTINS: Builtin[] = [
|
|
|
161
161
|
returns: "string",
|
|
162
162
|
doc: "HTTP request to an external API; returns the body as a string. Max 10 calls per script, 120s timeout, 5MB response.",
|
|
163
163
|
},
|
|
164
|
+
{
|
|
165
|
+
name: "fetchMail",
|
|
166
|
+
signature: "fetchMail(options)",
|
|
167
|
+
returns: "object",
|
|
168
|
+
doc: "Read new mail from one IMAP folder, read-only: nothing is marked seen, moved or deleted, so the mailbox stays the user's and the cursor you store says what was imported. Options: `host`, `username`, `secret` (the code of a module secret — the password is never written in a script), `port` (993; 143 with `security: 'starttls'`), `security` (`'ssl'` by default or `'starttls'`), `auth` (`'password'`, the only one for now), `folder` (`'INBOX'`), the cursor `uidValidity` + `afterUid` from the previous result, `since` (a date, for the first call), `limit` (messages). Returns `{ uidValidity, lastUid, more, reset, messages }`: store `uidValidity` and `lastUid` for the next call, call again while `more` is true, and treat `reset: true` as a mailbox renumbered by the server (the cursor was dropped and the folder read again). Each message has `uid`, `messageId`, `inReplyTo`, `references`, `date` (ISO 8601), `from`/`replyTo` (`{ address, name }`), `to`, `cc`, `envelopeTo`, `subject`, `text`, `html` (sanitized; remote images parked in `data-remote-src`), `autoReply`, `attachments` and `droppedAttachments`. Each attachment is a staged file `{ $tempId, fileName, mimeType, size, checksum, contentId, inline }`: pass it as the value of a `file` column in `insert()` / `update()` to keep it (an unused one expires with the temp sweep). Failures throw with the code first: `AUTH_FAILED`, `CONNECT_FAILED`, `TLS_FAILED`, `FOLDER_NOT_FOUND`; a host on a private network needs `Dsl:Limits:AllowedHosts`. Meant for scheduled jobs and async actions: up to 3 calls per run, 25 messages and 40 s per call (`Dsl:Limits:MaxMailFetchesPerExecution` / `MaxMailMessagesPerFetch` / `MailFetchBudgetSeconds`).",
|
|
169
|
+
},
|
|
164
170
|
{
|
|
165
171
|
name: "callService",
|
|
166
172
|
signature: "callService(name, args)",
|