@dforge-core/metadata 0.0.44 → 0.0.46

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 CHANGED
@@ -5,6 +5,38 @@ All notable changes to `@dforge-core/metadata` are documented here.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this package adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.0.46] — 2026-10-25
9
+
10
+ ### Added
11
+
12
+ - **Register column slots:** `REGISTER_COLUMN_SLOTS` lists every place a register declaration names a
13
+ stored column — the entity it lives on, what to call it, whether it is summed. `registerColumnSlot(path,
14
+ kind?)` resolves a path to its slot and `registerColumnHost(def, host)` names the entity a slot is on, so an
15
+ editor can offer the right entity's columns at a path. `checkRegister` reads columns through the same table.
16
+ - **`column-not-numeric` warning:** a column that a balance, turnover or accounting register adds up (its
17
+ resources, and its totals cache's) must store a scalar number. It runs when the `RegisterEntityLookup` returns
18
+ `datatypes` (a new optional `Map` of storage type per column) and skips a column whose type is unknown.
19
+ An information register's resources are returned, not summed, so they may be any type.
20
+ - `isNumericDatatype()` and the `RegisterHosts` type.
21
+
22
+ ### Changed
23
+
24
+ - **`unknown-column` message** for a register column quotes the entity: `... isn't a stored column of 'stock'.`
25
+
26
+ ## [0.0.45] — 2026-10-24
27
+
28
+ ### Added
29
+
30
+ - **DSL `attachText(content, fileName, encoding?, mimeType?)` / `attachBase64(base64, fileName,
31
+ mimeType?)`:** build a file for `sendEmail()`'s fourth argument, keeping its own type (an `.ics` as
32
+ `text/calendar`). Unlike a `printPdf()` result they have no owner, so a scheduled job can attach them.
33
+ Listed in `BUILTINS`; they share the per-run file limit with `downloadText()` / `downloadBase64()`.
34
+
35
+ ### Changed
36
+
37
+ - **DSL `sendEmail()`:** the attachments argument now accepts `attachText()` / `attachBase64()` results as
38
+ well as `printPdf()` ones.
39
+
8
40
  ## [0.0.44] — 2026-10-21
9
41
 
10
42
  ### Added
@@ -53,8 +53,26 @@ interface ActionDef {
53
53
  * "Run in Background". A parameterless `isAsync` action is queued directly.
54
54
  */
55
55
  isAsync?: boolean;
56
+ /**
57
+ * Code of a print template of the action's entity. The run dialog renders it as a PDF beside the params when the
58
+ * action is opened on one record, so the user sees the document the action sends before it goes.
59
+ */
60
+ previewTemplate?: string;
61
+ /**
62
+ * Saved parameter sets the module ships for this action, keyed by set name. They install as shared sets owned by
63
+ * the module: read-only for users and refreshed on every install, and a user can save a set of their own under the
64
+ * same name, which wins for them. Each `values` key must be a param the action declares; a string starting with `=`
65
+ * is a formula. Needs the action to declare params.
66
+ */
67
+ paramSets?: Record<string, ActionParamSetDef>;
68
+ }
69
+ /** One shipped parameter set of an action. */
70
+ interface ActionParamSetDef {
71
+ description?: string;
72
+ /** Value by param code. */
73
+ values: Record<string, unknown>;
56
74
  }
57
75
  /** A `ui/actions.json` file: action code → definition. */
58
76
  type ActionsFile = Record<string, ActionDef>;
59
77
 
60
- export type { ActionExecutionMode as A, ActionDef as a, ActionsFile as b };
78
+ export type { ActionExecutionMode as A, ActionDef as a, ActionParamSetDef as b, ActionsFile as c };
@@ -1,4 +1,4 @@
1
- import { A as ActionExecutionMode } from '../actions-DvYTrCbP.js';
1
+ import { A as ActionExecutionMode } from '../actions-D-0G_mqf.js';
2
2
 
3
3
  type TokenKind = "ident" | "number" | "string" | "template" | "regex" | "punct" | "comment";
4
4
  interface Token {
package/dist/dsl/index.js CHANGED
@@ -856,7 +856,7 @@ var BUILTINS = [
856
856
  name: "sendEmail",
857
857
  signature: "sendEmail(to, subjectOrTemplate, dataOrBody?, attachments?)",
858
858
  returns: "void",
859
- 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>\u2026</p>')` sends raw HTML. A second argument with no spaces that contains `.` or `_` is read as a template code \u2014 so a raw subject like `'Shipped.'` silently becomes one; give a raw subject spaces. The optional **fourth** argument attaches files: a `printPdf()` 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). Only a `printPdf()` result can be attached, and only by the user who generated it (or a workspace admin); 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. Not available in a scheduled job, whose emails with attachments are not queued."
859
+ 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>\u2026</p>')` sends raw HTML. A second argument with no spaces that contains `.` or `_` is read as a template code \u2014 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."
860
860
  },
861
861
  // External calls
862
862
  {
@@ -909,6 +909,18 @@ var BUILTINS = [
909
909
  returns: "string",
910
910
  doc: "`downloadText()` for bytes: decodes `base64` and hands it to the user as `fileName` (`application/octet-stream` unless `mimeType` says otherwise). Returns the signed download URL."
911
911
  },
912
+ {
913
+ name: "attachText",
914
+ signature: "attachText(content, fileName, encoding?, mimeType?)",
915
+ returns: "object",
916
+ doc: "Build a text file to attach to an email: encodes `content` in `encoding` (`utf-8` by default) and returns a descriptor for `sendEmail()`'s fourth argument, e.g. `sendEmail(to, 'Interview', body, attachText(ics, 'invite.ics', 'utf-8', 'text/calendar'))`. The file keeps `mimeType` (`text/plain` by default). It is the script's own output, so no user's rights are involved and it works in a scheduled job. Only the emails of this run can name it. Max 10 MB per file and 10 files per run, shared with `downloadText()` / `downloadBase64()`."
917
+ },
918
+ {
919
+ name: "attachBase64",
920
+ signature: "attachBase64(base64, fileName, mimeType?)",
921
+ returns: "object",
922
+ doc: "`attachText()` for bytes given as base64 (`application/octet-stream` unless `mimeType` says otherwise)."
923
+ },
912
924
  {
913
925
  name: "getSetting",
914
926
  signature: "getSetting(settingCd)",