@dforge-core/metadata 0.0.6 → 0.0.8
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 +11 -0
- package/dist/derive.d.ts.map +1 -1
- package/dist/derive.js +17 -0
- package/dist/derive.js.map +1 -1
- package/dist/triggers.d.ts +5 -1
- package/dist/triggers.d.ts.map +1 -1
- package/package.json +1 -1
- package/schemas/triggers.schema.json +1 -1
- package/src/derive.ts +18 -0
- package/src/triggers.ts +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,17 @@ 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.8] — 2026-07-17
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- `deriveDbDatatype` now returns `jsonb` (not `bytea`) for the `file` and `image`
|
|
13
|
+
field types, matching the server's `DdlService.ResolveDbTypeFromFieldType`.
|
|
14
|
+
These types classify as `binary`, but dForge stores a JSON metadata reference
|
|
15
|
+
(`{ storagePath, fileName, … }`) — the bytes live in file storage. Previously
|
|
16
|
+
an omitted `dbDatatype` on a file/image column derived `bytea`, which broke
|
|
17
|
+
file attachments on save.
|
|
18
|
+
|
|
8
19
|
## [0.0.3] — 2026-06-14
|
|
9
20
|
|
|
10
21
|
### Added
|
package/dist/derive.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive.d.ts","sourceRoot":"","sources":["../src/derive.ts"],"names":[],"mappings":"AASA,sEAAsE;AACtE,eAAO,MAAM,aAAa,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"derive.d.ts","sourceRoot":"","sources":["../src/derive.ts"],"names":[],"mappings":"AASA,sEAAsE;AACtE,eAAO,MAAM,aAAa,KAAK,CAAC;AAkBhC,MAAM,WAAW,aAAa;IAC7B,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,GAAG,IAAI,CA4BhG;AAED,+EAA+E;AAC/E,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAItF;AAED,uFAAuF;AACvF,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE1E"}
|
package/dist/derive.js
CHANGED
|
@@ -9,6 +9,18 @@ import { getFieldType } from "./field-types";
|
|
|
9
9
|
export const NUMERIC_TOTAL = 18;
|
|
10
10
|
/** Field types whose natural storage is unbounded `text` rather than `varchar`. */
|
|
11
11
|
const TEXT_BACKED = new Set(["textarea", "richtext", "code"]);
|
|
12
|
+
/**
|
|
13
|
+
* Field types the server pins to a fixed column type regardless of their base
|
|
14
|
+
* datatype — mirrors `DdlService.ResolveDbTypeFromFieldType`. `file`/`image`
|
|
15
|
+
* classify as `binary`, but dForge stores them as a JSON metadata reference
|
|
16
|
+
* (`{ storagePath, fileName, … }`), NOT inline `bytea`; the column is `jsonb`.
|
|
17
|
+
* Without this override the base path derives `bytea`, and the file-attach
|
|
18
|
+
* pipeline — which reads/writes that JSON — fails on save.
|
|
19
|
+
*/
|
|
20
|
+
const DB_DATATYPE_OVERRIDE = {
|
|
21
|
+
file: "jsonb",
|
|
22
|
+
image: "jsonb",
|
|
23
|
+
};
|
|
12
24
|
/**
|
|
13
25
|
* Derive the PostgreSQL `dbDatatype` for a field type. Returns `null` for
|
|
14
26
|
* field types backed by relationships/sets (lookup, grid) that have no physical
|
|
@@ -22,6 +34,11 @@ export function deriveDbDatatype(fieldTypeCd, options = {}) {
|
|
|
22
34
|
// column — the FK lives on a separate hidden column.
|
|
23
35
|
if (ft.columnType === "R" || ft.columnType === "S")
|
|
24
36
|
return null;
|
|
37
|
+
// Server-pinned column types that don't follow the base-datatype path
|
|
38
|
+
// (file/image → jsonb, not bytea). Mirrors ResolveDbTypeFromFieldType.
|
|
39
|
+
const override = DB_DATATYPE_OVERRIDE[ft.cd];
|
|
40
|
+
if (override)
|
|
41
|
+
return override;
|
|
25
42
|
const base = baseToDbDatatype(ft.baseDatatypeCd);
|
|
26
43
|
if (base === null)
|
|
27
44
|
return null; // other non-physical base (link/ref/set)
|
package/dist/derive.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derive.js","sourceRoot":"","sources":["../src/derive.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,yEAAyE;AACzE,EAAE;AACF,2EAA2E;AAC3E,+EAA+E;AAE/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,sEAAsE;AACtE,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAC;AAEhC,mFAAmF;AACnF,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"derive.js","sourceRoot":"","sources":["../src/derive.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,yEAAyE;AACzE,EAAE;AACF,2EAA2E;AAC3E,+EAA+E;AAE/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,sEAAsE;AACtE,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAC;AAEhC,mFAAmF;AACnF,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;AAE9D;;;;;;;GAOG;AACH,MAAM,oBAAoB,GAA2B;IACpD,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,OAAO;CACd,CAAC;AASF;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAmB,EAAE,UAAyB,EAAE;IAChF,MAAM,EAAE,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE;QAAE,OAAO,SAAS,CAAC;IAE1B,wEAAwE;IACxE,qDAAqD;IACrD,IAAI,EAAE,CAAC,UAAU,KAAK,GAAG,IAAI,EAAE,CAAC,UAAU,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAEhE,sEAAsE;IACtE,uEAAuE;IACvE,MAAM,QAAQ,GAAG,oBAAoB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC7C,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,IAAI,GAAG,gBAAgB,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC;IACjD,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC,CAAC,yCAAyC;IAEzE,IAAI,EAAE,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;QACpC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,SAAS,CAAC;QACpD,OAAO,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,WAAW,aAAa,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IACjF,CAAC;IAED,IAAI,EAAE,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;QACpC,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAAE,OAAO,MAAM,CAAC;QAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,MAAM,CAAC;QAC3C,OAAO,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,WAAW,MAAM,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1D,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,aAAa,CAAC,WAAmB;IAChD,MAAM,EAAE,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,EAAE,SAAS;QAAE,OAAO,SAAS,CAAC;IACrC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC;AAC5B,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,kBAAkB,CAAC,WAAmB;IACrD,OAAO,YAAY,CAAC,WAAW,CAAC,EAAE,cAAc,CAAC;AAClD,CAAC"}
|
package/dist/triggers.d.ts
CHANGED
|
@@ -14,7 +14,11 @@ export interface TriggerDef {
|
|
|
14
14
|
action: string;
|
|
15
15
|
/** Static parameters passed to the action, merged with the injected record id. */
|
|
16
16
|
params?: Record<string, unknown>;
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* true: run in the background after the triggering tx commits (failures logged, not surfaced).
|
|
19
|
+
* false (default): run synchronously in the same tx — a failure rolls the mutation back and
|
|
20
|
+
* returns the error to the caller. Keep async:false actions fast.
|
|
21
|
+
*/
|
|
18
22
|
async?: boolean;
|
|
19
23
|
}
|
|
20
24
|
/** A `logic/triggers.json` file. */
|
package/dist/triggers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"triggers.d.ts","sourceRoot":"","sources":["../src/triggers.ts"],"names":[],"mappings":"AAEA,6CAA6C;AAC7C,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,eAAe,GAAG,KAAK,CAAC;AAEnF,oCAAoC;AACpC,MAAM,WAAW,UAAU;IAC1B,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,CAAC;IACnB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC
|
|
1
|
+
{"version":3,"file":"triggers.d.ts","sourceRoot":"","sources":["../src/triggers.ts"],"names":[],"mappings":"AAEA,6CAA6C;AAC7C,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,eAAe,GAAG,KAAK,CAAC;AAEnF,oCAAoC;AACpC,MAAM,WAAW,UAAU;IAC1B,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,CAAC;IACnB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,oCAAoC;AACpC,MAAM,WAAW,YAAY;IAC5B,QAAQ,EAAE,UAAU,EAAE,CAAC;CACvB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dforge-core/metadata",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
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",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"async": {
|
|
51
51
|
"type": "boolean",
|
|
52
52
|
"default": false,
|
|
53
|
-
"description": "When true, the action runs in the background — the triggering transaction commits before the action starts. Recommended for slow actions (emails, external API calls). When false, the action runs
|
|
53
|
+
"description": "When true, the action runs in the background — the triggering transaction commits before the action starts. Recommended for slow actions (emails, external API calls); background failures are logged, not surfaced to the caller. When false, the action runs synchronously inside the same transaction as the triggering insert/update/delete: if the action fails (e.g. calls error()), the whole mutation rolls back and the error is returned to the caller. Keep async:false actions fast — they run on the request's transaction."
|
|
54
54
|
}
|
|
55
55
|
},
|
|
56
56
|
"additionalProperties": false
|
package/src/derive.ts
CHANGED
|
@@ -13,6 +13,19 @@ export const NUMERIC_TOTAL = 18;
|
|
|
13
13
|
/** Field types whose natural storage is unbounded `text` rather than `varchar`. */
|
|
14
14
|
const TEXT_BACKED = new Set(["textarea", "richtext", "code"]);
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Field types the server pins to a fixed column type regardless of their base
|
|
18
|
+
* datatype — mirrors `DdlService.ResolveDbTypeFromFieldType`. `file`/`image`
|
|
19
|
+
* classify as `binary`, but dForge stores them as a JSON metadata reference
|
|
20
|
+
* (`{ storagePath, fileName, … }`), NOT inline `bytea`; the column is `jsonb`.
|
|
21
|
+
* Without this override the base path derives `bytea`, and the file-attach
|
|
22
|
+
* pipeline — which reads/writes that JSON — fails on save.
|
|
23
|
+
*/
|
|
24
|
+
const DB_DATATYPE_OVERRIDE: Record<string, string> = {
|
|
25
|
+
file: "jsonb",
|
|
26
|
+
image: "jsonb",
|
|
27
|
+
};
|
|
28
|
+
|
|
16
29
|
export interface DeriveOptions {
|
|
17
30
|
/** Author-specified max length; overrides the field type's default. */
|
|
18
31
|
maxLen?: number | null;
|
|
@@ -33,6 +46,11 @@ export function deriveDbDatatype(fieldTypeCd: string, options: DeriveOptions = {
|
|
|
33
46
|
// column — the FK lives on a separate hidden column.
|
|
34
47
|
if (ft.columnType === "R" || ft.columnType === "S") return null;
|
|
35
48
|
|
|
49
|
+
// Server-pinned column types that don't follow the base-datatype path
|
|
50
|
+
// (file/image → jsonb, not bytea). Mirrors ResolveDbTypeFromFieldType.
|
|
51
|
+
const override = DB_DATATYPE_OVERRIDE[ft.cd];
|
|
52
|
+
if (override) return override;
|
|
53
|
+
|
|
36
54
|
const base = baseToDbDatatype(ft.baseDatatypeCd);
|
|
37
55
|
if (base === null) return null; // other non-physical base (link/ref/set)
|
|
38
56
|
|
package/src/triggers.ts
CHANGED
|
@@ -17,7 +17,11 @@ export interface TriggerDef {
|
|
|
17
17
|
action: string;
|
|
18
18
|
/** Static parameters passed to the action, merged with the injected record id. */
|
|
19
19
|
params?: Record<string, unknown>;
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* true: run in the background after the triggering tx commits (failures logged, not surfaced).
|
|
22
|
+
* false (default): run synchronously in the same tx — a failure rolls the mutation back and
|
|
23
|
+
* returns the error to the caller. Keep async:false actions fast.
|
|
24
|
+
*/
|
|
21
25
|
async?: boolean;
|
|
22
26
|
}
|
|
23
27
|
|