@dforge-core/metadata 0.0.36 → 0.0.38
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 +22 -0
- package/README.md +1 -1
- package/dist/dsl/index.js +3 -3
- package/dist/dsl/index.js.map +1 -1
- package/dist/index.d.ts +19 -3
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/package.json +67 -66
- package/schemas/demo_vars.schema.json +28 -0
- package/schemas/deps.schema.json +14 -2
- package/schemas/settings.schema.json +31 -0
- package/schemas/translations.schema.json +13 -1
- package/src/dsl/builtins.ts +3 -3
- package/src/index.ts +2 -1
- package/src/settings.ts +25 -2
package/package.json
CHANGED
|
@@ -1,67 +1,68 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
2
|
+
"name": "@dforge-core/metadata",
|
|
3
|
+
"version": "0.0.38",
|
|
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
|
+
"license": "MIT",
|
|
6
|
+
"author": "dForge",
|
|
7
|
+
"homepage": "https://github.com/iash44/dForge-core/tree/main/clients/packages/metadata#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/iash44/dForge-core.git",
|
|
11
|
+
"directory": "clients/packages/metadata"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/iash44/dForge-core/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"dforge",
|
|
18
|
+
"metadata",
|
|
19
|
+
"field-type",
|
|
20
|
+
"trait",
|
|
21
|
+
"registry",
|
|
22
|
+
"low-code"
|
|
23
|
+
],
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public"
|
|
26
|
+
},
|
|
27
|
+
"type": "module",
|
|
28
|
+
"main": "./dist/index.js",
|
|
29
|
+
"module": "./dist/index.js",
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"source": "./src/index.ts",
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"default": "./dist/index.js"
|
|
36
|
+
},
|
|
37
|
+
"./dsl": {
|
|
38
|
+
"source": "./src/dsl/index.ts",
|
|
39
|
+
"types": "./dist/dsl/index.d.ts",
|
|
40
|
+
"default": "./dist/dsl/index.js"
|
|
41
|
+
},
|
|
42
|
+
"./schemas/*": "./schemas/*",
|
|
43
|
+
"./package.json": "./package.json"
|
|
44
|
+
},
|
|
45
|
+
"sideEffects": false,
|
|
46
|
+
"files": [
|
|
47
|
+
"dist",
|
|
48
|
+
"src",
|
|
49
|
+
"schemas",
|
|
50
|
+
"CHANGELOG.md"
|
|
51
|
+
],
|
|
52
|
+
"scripts": {
|
|
53
|
+
"sync-schemas": "node scripts/sync-schemas.mjs",
|
|
54
|
+
"build": "tsup",
|
|
55
|
+
"dev": "tsup --watch",
|
|
56
|
+
"typecheck": "tsc -p tsconfig.build.json --noEmit",
|
|
57
|
+
"test": "vitest run",
|
|
58
|
+
"prepack": "pnpm sync-schemas && pnpm typecheck && pnpm build",
|
|
59
|
+
"package": "pnpm pack"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@types/node": "^25.9.4",
|
|
63
|
+
"ajv": "^8.20.0",
|
|
64
|
+
"tsup": "^8.5.1",
|
|
65
|
+
"typescript": "^6.0.3",
|
|
66
|
+
"vitest": "^4.1.10"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://dforge.dev/schemas/demo_vars.schema.json",
|
|
4
|
+
"title": "dForge Demo Data Variables",
|
|
5
|
+
"description": "demo-data/vars.json: the variables demo-data formulas read as @name. A flat map of variable name to value. It is not a data file; the loader skips it, and each module has its own (nothing is shared between modules).",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"propertyNames": {
|
|
8
|
+
"pattern": "^[A-Za-z_][A-Za-z0-9_]*$",
|
|
9
|
+
"description": "A letter or underscore, then letters, digits or underscores. Names are case-insensitive, and a repeat variable of the same name shadows the file's."
|
|
10
|
+
},
|
|
11
|
+
"additionalProperties": {
|
|
12
|
+
"description": "A plain value (string, number, boolean or null) is substituted as a literal. { \"$f\": \"...\" } is a formula expanded where the variable is used, e.g. { \"$f\": \"DATEADD(TODAY(), -30, 'DAY')\" }; it may read other variables with @name (a cycle fails the install) but not [column] values.",
|
|
13
|
+
"oneOf": [
|
|
14
|
+
{ "type": ["string", "number", "boolean", "null"] },
|
|
15
|
+
{
|
|
16
|
+
"type": "object",
|
|
17
|
+
"required": ["$f"],
|
|
18
|
+
"properties": {
|
|
19
|
+
"$f": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"description": "Formula whose result is the variable's value"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"additionalProperties": false
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
}
|
package/schemas/deps.schema.json
CHANGED
|
@@ -18,12 +18,24 @@
|
|
|
18
18
|
},
|
|
19
19
|
"entities": {
|
|
20
20
|
"type": "object",
|
|
21
|
-
"description": "Consumed provider entities, keyed by entity code (e.g. 'party'). At least one, except against a system module (admin, metadata, workspace, sys-billing), where {} declares a pure platform-version gate for a feature that introduced no entity.",
|
|
21
|
+
"description": "Consumed provider entities, keyed by entity code (e.g. 'party'). At least one, except against a system module (admin, metadata, workspace, sys-billing), where {} declares a pure platform-version gate for a feature that introduced no entity, or when 'functions' imports at least one function.",
|
|
22
22
|
"additionalProperties": { "$ref": "#/definitions/entityContract" }
|
|
23
|
+
},
|
|
24
|
+
"functions": {
|
|
25
|
+
"type": "array",
|
|
26
|
+
"description": "The provider's DSL library functions (logic/functions/*.dsl) the consumer's actions call, as <provider code with '-' replaced by '_'>.<name>(...). Only listed names are reachable, and install checks the installed provider declares each. See docs/business-logic/dsl-functions.md.",
|
|
27
|
+
"items": { "type": "string", "pattern": "^[A-Za-z_$][A-Za-z0-9_$]*$" },
|
|
28
|
+
"uniqueItems": true,
|
|
29
|
+
"minItems": 1
|
|
23
30
|
}
|
|
24
31
|
},
|
|
25
32
|
"if": {
|
|
26
|
-
"not": {
|
|
33
|
+
"not": {
|
|
34
|
+
"anyOf": [
|
|
35
|
+
{ "properties": { "module": { "enum": ["admin", "metadata", "workspace", "sys-billing"] } }, "required": ["module"] },
|
|
36
|
+
{ "required": ["functions"] }
|
|
37
|
+
]
|
|
38
|
+
}
|
|
27
39
|
},
|
|
28
40
|
"then": {
|
|
29
41
|
"properties": { "entities": { "minProperties": 1 } }
|
|
@@ -4,10 +4,41 @@
|
|
|
4
4
|
"title": "dForge Module Settings",
|
|
5
5
|
"description": "Module-level settings definitions: a flat map of setting code → setting definition. Settings are folder-scoped at runtime (values inherit through the folder tree) and surface in the Module Settings UI.",
|
|
6
6
|
"type": "object",
|
|
7
|
+
"propertyNames": {
|
|
8
|
+
"pattern": "^(\\$constraints|[^$].*)$",
|
|
9
|
+
"description": "A setting code cannot start with '$'; $constraints is the only reserved key."
|
|
10
|
+
},
|
|
11
|
+
"properties": {
|
|
12
|
+
"$constraints": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"description": "Checks across this module's settings, keyed by constraint name. The settings are the columns of one virtual row, so each is an entity check constraint: SQL over setting codes. settings.set and settings.setMany run every rule naming a written setting, at the folder written and at each folder below it that overrides a setting the rule names; install refuses defaults that fail one. NULL passes, as in a CHECK.",
|
|
15
|
+
"additionalProperties": {
|
|
16
|
+
"$ref": "#/$defs/constraint"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
7
20
|
"additionalProperties": {
|
|
8
21
|
"$ref": "#/$defs/setting"
|
|
9
22
|
},
|
|
10
23
|
"$defs": {
|
|
24
|
+
"constraint": {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"required": ["type", "expression"],
|
|
27
|
+
"additionalProperties": false,
|
|
28
|
+
"properties": {
|
|
29
|
+
"type": {
|
|
30
|
+
"const": "check"
|
|
31
|
+
},
|
|
32
|
+
"expression": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"description": "Boolean over this module's settings in SQL CHECK syntax, e.g. \"default_discount_pct <= max_discount_pct\": comparisons, IS [NOT] NULL, [NOT] IN, [NOT] BETWEEN, regex matches (~ ~* !~ !~*) against a string literal, AND/OR/NOT, + - * /, literals and setting codes (bare or \"quoted\"). No functions, casts or [field] brackets; IS NULL rather than = null. The settings it names are found in it: writing any of them re-checks the rule."
|
|
35
|
+
},
|
|
36
|
+
"message": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"description": "Violation message. Localizable via translations/<locale>.json under settings.$constraints.<name>.message."
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
11
42
|
"setting": {
|
|
12
43
|
"type": "object",
|
|
13
44
|
"properties": {
|
|
@@ -46,7 +46,19 @@
|
|
|
46
46
|
},
|
|
47
47
|
"settings": {
|
|
48
48
|
"type": "object",
|
|
49
|
-
"description": "Setting code (settings.json) → label and description.",
|
|
49
|
+
"description": "Setting code (settings.json) → label and description; $constraints → constraint name → message.",
|
|
50
|
+
"properties": {
|
|
51
|
+
"$constraints": {
|
|
52
|
+
"type": "object",
|
|
53
|
+
"additionalProperties": {
|
|
54
|
+
"type": "object",
|
|
55
|
+
"additionalProperties": false,
|
|
56
|
+
"properties": {
|
|
57
|
+
"message": { "type": "string" }
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
50
62
|
"additionalProperties": {
|
|
51
63
|
"$ref": "#/$defs/labelDesc"
|
|
52
64
|
}
|
package/src/dsl/builtins.ts
CHANGED
|
@@ -227,9 +227,9 @@ export const BUILTINS: Builtin[] = [
|
|
|
227
227
|
|
|
228
228
|
// Utilities
|
|
229
229
|
{ name: "now", signature: "now()", returns: "datetime", doc: "Current date/time. Lowercase — this is the execute-block date function." },
|
|
230
|
-
{ name: "addDays", signature: "addDays(date, n)", returns: "date", doc: "Add `n` days
|
|
231
|
-
{ name: "addMinutes", signature: "addMinutes(date, n)", returns: "datetime", doc: "Add `n` minutes." },
|
|
232
|
-
{ name: "addSeconds", signature: "addSeconds(date, n)", returns: "datetime", doc: "Add `n` seconds." },
|
|
230
|
+
{ name: "addDays", signature: "addDays(date, n)", returns: "date | string", doc: "Add `n` days. Takes a date field, a `Date` or an ISO string; a date field stays a date and a `yyyy-MM-dd` string stays a string. Null stays null; any other value is an error." },
|
|
231
|
+
{ name: "addMinutes", signature: "addMinutes(date, n)", returns: "datetime", doc: "Add `n` minutes. Takes a date field, a `Date` or an ISO string; the result is a timestamp. Null stays null; any other value is an error." },
|
|
232
|
+
{ name: "addSeconds", signature: "addSeconds(date, n)", returns: "datetime", doc: "Add `n` seconds. Takes a date field, a `Date` or an ISO string; the result is a timestamp. Null stays null; any other value is an error." },
|
|
233
233
|
{ name: "currentUserId", signature: "currentUserId()", returns: "long", doc: "The acting user's tenant user ID." },
|
|
234
234
|
{ name: "flush", signature: "flush()", returns: "void", doc: "Flush pending writes so a following read sees them." },
|
|
235
235
|
{ name: "tryParseJson", signature: "tryParseJson(value)", returns: "any | null", doc: "Parse JSON, returning `null` on failure instead of throwing." },
|
package/src/index.ts
CHANGED
|
@@ -132,7 +132,8 @@ export type {
|
|
|
132
132
|
TranslatedReport,
|
|
133
133
|
TranslatedWithOptions,
|
|
134
134
|
} from "./translations";
|
|
135
|
-
export
|
|
135
|
+
export { settingDefsOf } from "./settings";
|
|
136
|
+
export type { SettingsFile, SettingDef, SettingConstraintDef, SettingBaseDatatype } from "./settings";
|
|
136
137
|
export {
|
|
137
138
|
REGISTER_KINDS,
|
|
138
139
|
REGISTER_CODE,
|
package/src/settings.ts
CHANGED
|
@@ -38,5 +38,28 @@ export type SettingDef =
|
|
|
38
38
|
params?: never;
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
/** A
|
|
42
|
-
export
|
|
41
|
+
/** A check across a module's settings: SQL over setting codes, as an entity check constraint. */
|
|
42
|
+
export interface SettingConstraintDef {
|
|
43
|
+
type: "check";
|
|
44
|
+
/** PostgreSQL boolean over setting codes; writing any setting it names re-checks it. */
|
|
45
|
+
expression: string;
|
|
46
|
+
message?: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* A `settings.json` file: setting code → definition, plus the optional `$constraints`. A
|
|
51
|
+
* setting code cannot start with `$`, but TypeScript cannot exclude it from the index, so
|
|
52
|
+
* the index admits the constraints map too.
|
|
53
|
+
*/
|
|
54
|
+
export type SettingsFile = {
|
|
55
|
+
$constraints?: Record<string, SettingConstraintDef>;
|
|
56
|
+
[settingCd: string]: SettingDef | Record<string, SettingConstraintDef> | undefined;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/** The settings of a file, without its `$constraints`. */
|
|
60
|
+
export function settingDefsOf(file: SettingsFile): Record<string, SettingDef> {
|
|
61
|
+
const defs: Record<string, SettingDef> = {};
|
|
62
|
+
for (const [code, def] of Object.entries(file))
|
|
63
|
+
if (code !== "$constraints" && def) defs[code] = def as SettingDef;
|
|
64
|
+
return defs;
|
|
65
|
+
}
|