@antelopejs/interface-dms-builder 0.4.0 → 0.5.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.
- package/README.md +4 -4
- package/dist/addressing.d.ts +6 -0
- package/dist/analysis.d.ts +73 -0
- package/dist/analysis.js +18 -1
- package/dist/analysis.js.map +1 -1
- package/dist/catalog.d.ts +139 -1
- package/dist/compose.d.ts +44 -0
- package/dist/compose.js +7 -0
- package/dist/compose.js.map +1 -1
- package/dist/database.d.ts +230 -0
- package/dist/database.js +80 -0
- package/dist/database.js.map +1 -0
- package/dist/drafts.d.ts +61 -0
- package/dist/drafts.js +21 -0
- package/dist/drafts.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/mapping.d.ts +122 -0
- package/dist/mapping.js +15 -0
- package/dist/mapping.js.map +1 -1
- package/dist/operation-map.d.ts +27 -1
- package/dist/operation-map.js +22 -0
- package/dist/operation-map.js.map +1 -1
- package/dist/operations.d.ts +57 -0
- package/dist/operations.js +18 -0
- package/dist/operations.js.map +1 -1
- package/dist/project.d.ts +63 -1
- package/dist/project.js +10 -0
- package/dist/project.js.map +1 -1
- package/dist/queries.d.ts +125 -0
- package/dist/resources.d.ts +132 -0
- package/dist/resources.js +9 -0
- package/dist/resources.js.map +1 -1
- package/dist/results.d.ts +49 -1
- package/dist/structure.d.ts +42 -0
- package/dist/table-view.d.ts +49 -0
- package/dist/table-view.js +7 -0
- package/dist/table-view.js.map +1 -1
- package/dist/theme.d.ts +144 -0
- package/dist/theme.js +46 -0
- package/dist/theme.js.map +1 -0
- package/dist/values.d.ts +64 -0
- package/dist/values.js +7 -0
- package/dist/values.js.map +1 -1
- package/docs/1.introduction.md +3 -0
- package/docs/10.a-chart-without-code.md +7 -7
- package/docs/11.external-databases.md +16 -11
- package/docs/11.theme-and-branding.md +135 -0
- package/docs/12.connect-a-database.md +87 -0
- package/docs/4.page-operations.md +1 -1
- package/package.json +15 -8
package/dist/table-view.d.ts
CHANGED
|
@@ -1,32 +1,54 @@
|
|
|
1
1
|
import type { BlockPath } from "./addressing";
|
|
2
2
|
import type { MutationOpts, OpResult } from "./results";
|
|
3
|
+
/** The displays a table page can offer: the grid, a board, a card per row, rows under group headers. */
|
|
3
4
|
export type TableDisplayId = "table" | "kanban" | "cards" | "grouped";
|
|
5
|
+
/**
|
|
6
|
+
* A board of cards, one column per value of a single-choice column: a select that is not
|
|
7
|
+
* multiple, a boolean or a status.
|
|
8
|
+
*/
|
|
4
9
|
export interface KanbanSetting {
|
|
10
|
+
/** A single-choice column of the table. */
|
|
5
11
|
groupBy: string;
|
|
12
|
+
/** Cards move between columns by drag and drop. Default true. */
|
|
6
13
|
draggable?: boolean;
|
|
7
14
|
}
|
|
15
|
+
/** The grid with a header row per group of rows. */
|
|
8
16
|
export interface GroupedSetting {
|
|
17
|
+
/** A sortable column of the table. `day` and `week` need a date column. */
|
|
9
18
|
groupBy: string;
|
|
10
19
|
by?: "value" | "day" | "week";
|
|
20
|
+
/** A click on a group header folds its rows. */
|
|
11
21
|
collapsible?: boolean;
|
|
22
|
+
/** Group headers show how many rows they hold; needs a filterable `groupBy`. */
|
|
12
23
|
count?: boolean;
|
|
13
24
|
}
|
|
25
|
+
/** A card per row: its title, then these columns. */
|
|
14
26
|
export interface CardsSetting {
|
|
27
|
+
/** Listable columns of the table shown under the card's title; the first few when left out. */
|
|
15
28
|
fields?: string[];
|
|
16
29
|
}
|
|
30
|
+
/** How a view compares a column with its value. */
|
|
17
31
|
export type ViewFilterMode = "is" | "is_not" | "include" | "exclude" | "contains" | "not_contains" | "greater_than" | "less_than" | "greater_than_or_equal_to" | "less_than_or_equal_to" | "is_empty" | "is_not_empty";
|
|
32
|
+
/** One filter of a view. A value may hold the tokens `{{user.id}}`, `{{now}}` and `{{now-7d}}`. */
|
|
18
33
|
export interface ViewFilterSetting {
|
|
34
|
+
/** A filterable column of the table. */
|
|
19
35
|
column: string;
|
|
36
|
+
/** Default `is`. */
|
|
20
37
|
mode?: ViewFilterMode;
|
|
38
|
+
/** A list is joined with commas. Not needed for `is_empty` and `is_not_empty`. */
|
|
21
39
|
value?: string | string[];
|
|
22
40
|
}
|
|
41
|
+
/** A named state of the table: the rows and the way they are drawn. */
|
|
23
42
|
export interface ViewSetting {
|
|
43
|
+
/** Stable, lower-case, used in the URL: `late-orders`. */
|
|
24
44
|
id: string;
|
|
25
45
|
label: string;
|
|
26
46
|
icon?: string;
|
|
47
|
+
/** Shows how many rows the view lists. */
|
|
27
48
|
count?: boolean;
|
|
28
49
|
filters?: ViewFilterSetting[];
|
|
29
50
|
search?: string;
|
|
51
|
+
/** The rows are sorted on the first entry. Sortable columns only. */
|
|
30
52
|
sort?: {
|
|
31
53
|
column: string;
|
|
32
54
|
desc?: boolean;
|
|
@@ -36,39 +58,66 @@ export interface ViewSetting {
|
|
|
36
58
|
hidden?: string[];
|
|
37
59
|
order?: string[];
|
|
38
60
|
};
|
|
61
|
+
/** One of the displays the table offers. */
|
|
39
62
|
display?: TableDisplayId;
|
|
40
63
|
density?: "default" | "compact";
|
|
41
64
|
}
|
|
65
|
+
/** The named views of a table. */
|
|
42
66
|
export interface ViewsSetting {
|
|
43
67
|
items: ViewSetting[];
|
|
68
|
+
/** Where the views are drawn. Default `tabs`. */
|
|
44
69
|
layout?: "tabs" | "strip" | "menu";
|
|
70
|
+
/** The id of the view opened on arrival. */
|
|
45
71
|
defaultView?: string;
|
|
72
|
+
/** Users may save the current state as a view of their own. */
|
|
46
73
|
userViews?: boolean;
|
|
47
74
|
}
|
|
75
|
+
/** A figure of the footer band, computed over every row the table's filters list. */
|
|
48
76
|
export interface FooterSummarySetting {
|
|
77
|
+
/** Shown before the figure: `Total`. */
|
|
49
78
|
label: string;
|
|
79
|
+
/** `sum` adds up a number or price column; `count` counts the rows. */
|
|
50
80
|
op: "sum" | "count";
|
|
81
|
+
/** The column summed. Required by `sum`. */
|
|
51
82
|
field?: string;
|
|
83
|
+
/** Only the rows where `column` compares to `value` are summed or counted. */
|
|
52
84
|
where?: {
|
|
53
85
|
column: string;
|
|
54
86
|
op: "equals" | "notEquals" | "in" | "notIn";
|
|
55
87
|
value: string | number | boolean | (string | number | boolean)[];
|
|
56
88
|
};
|
|
57
89
|
}
|
|
90
|
+
/** The footer band of a table. */
|
|
58
91
|
export interface FooterSetting {
|
|
92
|
+
/** Replaces the footer's figures. An empty list removes them. */
|
|
59
93
|
summary?: FooterSummarySetting[];
|
|
60
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* What to set on a table page. A key left out is left as the page has it; `null` removes it.
|
|
97
|
+
* Column names are the controller's, as `GetResourceStructure` lists them.
|
|
98
|
+
*/
|
|
61
99
|
export interface TableViewSettings {
|
|
62
100
|
kanban?: KanbanSetting | null;
|
|
63
101
|
grouped?: GroupedSetting | null;
|
|
102
|
+
/** Offers the cards display. `null` stops offering it. */
|
|
64
103
|
cards?: CardsSetting | null;
|
|
104
|
+
/** The display shown first, one the table offers. `null` goes back to the first offered. */
|
|
65
105
|
defaultDisplay?: TableDisplayId | null;
|
|
66
106
|
views?: ViewsSetting | null;
|
|
67
107
|
footer?: FooterSetting | null;
|
|
68
108
|
}
|
|
109
|
+
/** Options for `ConfigureTableView`. */
|
|
69
110
|
export interface ConfigureTableViewOpts extends MutationOpts {
|
|
111
|
+
/** The name of the TableView block when the page holds several. */
|
|
70
112
|
block?: string;
|
|
71
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Sets displays, named views and footer figures on the TableView of a page, checking each
|
|
116
|
+
* against the columns of the table it reads: a kanban needs a single-choice column, a sum a
|
|
117
|
+
* number or price column, a view's filters filterable columns and its sort sortable ones. A
|
|
118
|
+
* footer figure also mounts the controller's summary route when it does not serve it. Nothing
|
|
119
|
+
* is written when a choice is refused, or when the page would not typecheck.
|
|
120
|
+
*/
|
|
72
121
|
export declare const ConfigureTableView: (page: string, settings: TableViewSettings, opts?: ConfigureTableViewOpts | undefined) => Promise<OpResult<{
|
|
73
122
|
path: BlockPath;
|
|
74
123
|
}>>;
|
package/dist/table-view.js
CHANGED
|
@@ -2,5 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ConfigureTableView = void 0;
|
|
4
4
|
const interface_core_1 = require("@antelopejs/interface-core");
|
|
5
|
+
/**
|
|
6
|
+
* Sets displays, named views and footer figures on the TableView of a page, checking each
|
|
7
|
+
* against the columns of the table it reads: a kanban needs a single-choice column, a sum a
|
|
8
|
+
* number or price column, a view's filters filterable columns and its sort sortable ones. A
|
|
9
|
+
* footer figure also mounts the controller's summary route when it does not serve it. Nothing
|
|
10
|
+
* is written when a choice is refused, or when the page would not typecheck.
|
|
11
|
+
*/
|
|
5
12
|
exports.ConfigureTableView = (0, interface_core_1.InterfaceFunction)();
|
|
6
13
|
//# sourceMappingURL=table-view.js.map
|
package/dist/table-view.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-view.js","sourceRoot":"","sources":["../src/table-view.ts"],"names":[],"mappings":";;;AAAA,+DAA+D;
|
|
1
|
+
{"version":3,"file":"table-view.js","sourceRoot":"","sources":["../src/table-view.ts"],"names":[],"mappings":";;;AAAA,+DAA+D;AAoI/D;;;;;;GAMG;AACU,QAAA,kBAAkB,GAC7B,IAAA,kCAAiB,GAMd,CAAC"}
|
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type { MutationOpts, OpResult } from "./results";
|
|
2
|
+
/** The two color modes a theme value can be set for. */
|
|
3
|
+
export type ThemeMode = "light" | "dark";
|
|
4
|
+
/** CSS custom properties by name: `{ "--ui-bg": "#fafafa" }`. */
|
|
5
|
+
export type ThemeVariables = Record<string, string>;
|
|
6
|
+
/**
|
|
7
|
+
* The CSS custom properties a theme overrides: those both modes share, and
|
|
8
|
+
* those set for one mode only.
|
|
9
|
+
*
|
|
10
|
+
* A variable left out keeps the DMS default, so a theme only holds what it
|
|
11
|
+
* changes. A shared value, such as the font or the corner radius, applies to
|
|
12
|
+
* both modes unless a mode sets its own.
|
|
13
|
+
*/
|
|
14
|
+
export interface ThemeVariableSets {
|
|
15
|
+
shared: ThemeVariables;
|
|
16
|
+
light: ThemeVariables;
|
|
17
|
+
dark: ThemeVariables;
|
|
18
|
+
}
|
|
19
|
+
/** The Nuxt UI color roles a theme picks a palette for. */
|
|
20
|
+
export type ThemeColorRole = "primary" | "success" | "warning" | "error" | "info";
|
|
21
|
+
/**
|
|
22
|
+
* The palette each role takes, by name: a Tailwind palette (`violet`), or one
|
|
23
|
+
* the project's stylesheets declare (`brand` for `--color-brand-50…950`). A
|
|
24
|
+
* role left out keeps the DMS palette.
|
|
25
|
+
*/
|
|
26
|
+
export type ThemeColors = Partial<Record<ThemeColorRole, string>>;
|
|
27
|
+
/** Where the dashboard shows a logo. */
|
|
28
|
+
export type LogoSlot = "default" | "collapsed" | "email" | "favicon";
|
|
29
|
+
/** Public paths, as the browser requests them: `/branding/logo.svg`. */
|
|
30
|
+
export type LogoPathsByMode = Partial<Record<ThemeMode, string>>;
|
|
31
|
+
/** A slot or a mode left out keeps the DMS logo. */
|
|
32
|
+
export type ThemeLogos = Partial<Record<LogoSlot, LogoPathsByMode>>;
|
|
33
|
+
/** A logo file sent with a save, for one slot in one color mode. */
|
|
34
|
+
export interface LogoUpload {
|
|
35
|
+
slot: LogoSlot;
|
|
36
|
+
mode: ThemeMode;
|
|
37
|
+
/**
|
|
38
|
+
* `image/svg+xml`, `image/png`, `image/jpeg`, `image/webp`, or
|
|
39
|
+
* `image/x-icon` (also as `image/vnd.microsoft.icon`). The `email` slot
|
|
40
|
+
* takes `image/png` or `image/jpeg` only, the formats every mail client
|
|
41
|
+
* shows.
|
|
42
|
+
*/
|
|
43
|
+
contentType: string;
|
|
44
|
+
base64Content: string;
|
|
45
|
+
}
|
|
46
|
+
/** The project's frontend layer a theme is read from and written to. */
|
|
47
|
+
export interface ThemeLayer {
|
|
48
|
+
name: string;
|
|
49
|
+
/** Absolute path of the layer's source directory. */
|
|
50
|
+
sourcePath: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The files a theme lives in, relative to the layer's source directory. All
|
|
54
|
+
* but the entry are under the directory the DMS frontend loader reads them
|
|
55
|
+
* from: the layer itself, or the last of its `layers/` by name when it has
|
|
56
|
+
* that directory.
|
|
57
|
+
*/
|
|
58
|
+
export interface ThemeFiles {
|
|
59
|
+
/** The unlayered stylesheet holding the variables. */
|
|
60
|
+
stylesheetPath: string;
|
|
61
|
+
/** The app config holding `ui.colors` and `branding.logo`. */
|
|
62
|
+
appConfigPath: string;
|
|
63
|
+
/** The layer's entry, which imports the stylesheet. */
|
|
64
|
+
entryPath: string;
|
|
65
|
+
/**
|
|
66
|
+
* Where uploaded logos are written, under the theme's `public/`, and the
|
|
67
|
+
* files of the fonts it hosts, in its `fonts/`.
|
|
68
|
+
*/
|
|
69
|
+
assetsDirectory: string;
|
|
70
|
+
}
|
|
71
|
+
/** A project's theme as its files hold it. */
|
|
72
|
+
export interface ThemeStructure {
|
|
73
|
+
layer: ThemeLayer;
|
|
74
|
+
variables: ThemeVariableSets;
|
|
75
|
+
colors: ThemeColors;
|
|
76
|
+
logos: ThemeLogos;
|
|
77
|
+
files: ThemeFiles;
|
|
78
|
+
/**
|
|
79
|
+
* Whether the layer's entry already imports the stylesheet. If not, the
|
|
80
|
+
* first save adds the import, and the development server then reloads the
|
|
81
|
+
* whole page.
|
|
82
|
+
*/
|
|
83
|
+
stylesheetImported: boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Hash of the stylesheet, app config and entry (not the logo files) → pass
|
|
86
|
+
* back as `expectedVersion`.
|
|
87
|
+
*/
|
|
88
|
+
version: string;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* A theme as it should be written: the whole of it, replacing the one on disk.
|
|
92
|
+
*
|
|
93
|
+
* An upload replaces whatever `logos` says for its slot and mode, since the
|
|
94
|
+
* server names the file after a hash of its (sanitized) content.
|
|
95
|
+
*/
|
|
96
|
+
export interface ThemeDraft {
|
|
97
|
+
variables: ThemeVariableSets;
|
|
98
|
+
colors: ThemeColors;
|
|
99
|
+
logos: ThemeLogos;
|
|
100
|
+
uploads?: LogoUpload[];
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The project's theme, read from its frontend layer.
|
|
104
|
+
*
|
|
105
|
+
* The layer is the highest-priority frontend module registered from inside the
|
|
106
|
+
* project root, unless the module config names one. Fails with:
|
|
107
|
+
* - `not_found` when the project has no layer, its `ref` naming where
|
|
108
|
+
* `CreateThemeLayer` would create it; or when the layer's entry file is
|
|
109
|
+
* missing, its `ref` naming that file (`CreateThemeLayer` does not fix it);
|
|
110
|
+
* - `unsupported` when the stylesheet holds rules the builder does not write,
|
|
111
|
+
* or when the layer has a `layers/` directory with no layer in it.
|
|
112
|
+
*/
|
|
113
|
+
export declare const GetTheme: () => Promise<OpResult<ThemeStructure>>;
|
|
114
|
+
/**
|
|
115
|
+
* Write a theme: its stylesheet, `ui.colors` and the logo paths of its app
|
|
116
|
+
* config, the logo files, and the entry's import of the stylesheet when it
|
|
117
|
+
* lacks one. One transaction: every file is checked before any is written.
|
|
118
|
+
*
|
|
119
|
+
* A variable whose value starts with a font the builder hosts
|
|
120
|
+
* (`--font-sans: "Inter", sans-serif`) gets that font's files, downloaded
|
|
121
|
+
* once from Fontsource, and its `@font-face` rules in the stylesheet; one the
|
|
122
|
+
* theme no longer uses is deleted. A download that fails is refused with
|
|
123
|
+
* `unsupported`, nothing written.
|
|
124
|
+
*
|
|
125
|
+
* SVG logos are written sanitized; the save warns (`svg_sanitized`) when that
|
|
126
|
+
* removed anything that runs or fetches. A palette or a logo path the
|
|
127
|
+
* builder cannot rewrite (anything but a string literal, or any key of an
|
|
128
|
+
* object with a spread) is kept as written; a draft that changes one is
|
|
129
|
+
* refused with `unsupported`, naming its key path. A draft not shaped like
|
|
130
|
+
* `ThemeDraft` is refused with `invalid_config`.
|
|
131
|
+
*/
|
|
132
|
+
export declare const SetTheme: (draft: ThemeDraft, opts?: MutationOpts | undefined) => Promise<OpResult<{
|
|
133
|
+
version: string;
|
|
134
|
+
}>>;
|
|
135
|
+
/**
|
|
136
|
+
* Create the frontend layer a theme is written to, for a project without one:
|
|
137
|
+
* `frontend-vue/` at the project root, with an entry importing the stylesheet,
|
|
138
|
+
* registered from the project's `start()` above the DMS. A project that
|
|
139
|
+
* already has a layer gets it back unchanged, and nothing is written.
|
|
140
|
+
*
|
|
141
|
+
* The backend reloads with the registration; the frontend dev server reads
|
|
142
|
+
* its frontend modules at startup, so it needs a restart to serve the layer.
|
|
143
|
+
*/
|
|
144
|
+
export declare const CreateThemeLayer: () => Promise<OpResult<ThemeLayer>>;
|
package/dist/theme.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CreateThemeLayer = exports.SetTheme = exports.GetTheme = void 0;
|
|
4
|
+
const interface_core_1 = require("@antelopejs/interface-core");
|
|
5
|
+
/**
|
|
6
|
+
* The project's theme, read from its frontend layer.
|
|
7
|
+
*
|
|
8
|
+
* The layer is the highest-priority frontend module registered from inside the
|
|
9
|
+
* project root, unless the module config names one. Fails with:
|
|
10
|
+
* - `not_found` when the project has no layer, its `ref` naming where
|
|
11
|
+
* `CreateThemeLayer` would create it; or when the layer's entry file is
|
|
12
|
+
* missing, its `ref` naming that file (`CreateThemeLayer` does not fix it);
|
|
13
|
+
* - `unsupported` when the stylesheet holds rules the builder does not write,
|
|
14
|
+
* or when the layer has a `layers/` directory with no layer in it.
|
|
15
|
+
*/
|
|
16
|
+
exports.GetTheme = (0, interface_core_1.InterfaceFunction)();
|
|
17
|
+
/**
|
|
18
|
+
* Write a theme: its stylesheet, `ui.colors` and the logo paths of its app
|
|
19
|
+
* config, the logo files, and the entry's import of the stylesheet when it
|
|
20
|
+
* lacks one. One transaction: every file is checked before any is written.
|
|
21
|
+
*
|
|
22
|
+
* A variable whose value starts with a font the builder hosts
|
|
23
|
+
* (`--font-sans: "Inter", sans-serif`) gets that font's files, downloaded
|
|
24
|
+
* once from Fontsource, and its `@font-face` rules in the stylesheet; one the
|
|
25
|
+
* theme no longer uses is deleted. A download that fails is refused with
|
|
26
|
+
* `unsupported`, nothing written.
|
|
27
|
+
*
|
|
28
|
+
* SVG logos are written sanitized; the save warns (`svg_sanitized`) when that
|
|
29
|
+
* removed anything that runs or fetches. A palette or a logo path the
|
|
30
|
+
* builder cannot rewrite (anything but a string literal, or any key of an
|
|
31
|
+
* object with a spread) is kept as written; a draft that changes one is
|
|
32
|
+
* refused with `unsupported`, naming its key path. A draft not shaped like
|
|
33
|
+
* `ThemeDraft` is refused with `invalid_config`.
|
|
34
|
+
*/
|
|
35
|
+
exports.SetTheme = (0, interface_core_1.InterfaceFunction)();
|
|
36
|
+
/**
|
|
37
|
+
* Create the frontend layer a theme is written to, for a project without one:
|
|
38
|
+
* `frontend-vue/` at the project root, with an entry importing the stylesheet,
|
|
39
|
+
* registered from the project's `start()` above the DMS. A project that
|
|
40
|
+
* already has a layer gets it back unchanged, and nothing is written.
|
|
41
|
+
*
|
|
42
|
+
* The backend reloads with the registration; the frontend dev server reads
|
|
43
|
+
* its frontend modules at startup, so it needs a restart to serve the layer.
|
|
44
|
+
*/
|
|
45
|
+
exports.CreateThemeLayer = (0, interface_core_1.InterfaceFunction)();
|
|
46
|
+
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":";;;AAAA,+DAA+D;AAyH/D;;;;;;;;;;GAUG;AACU,QAAA,QAAQ,GACnB,IAAA,kCAAiB,GAA2C,CAAC;AAE/D;;;;;;;;;;;;;;;;;GAiBG;AACU,QAAA,QAAQ,GACnB,IAAA,kCAAiB,GAKd,CAAC;AAEN;;;;;;;;GAQG;AACU,QAAA,gBAAgB,GAC3B,IAAA,kCAAiB,GAAuC,CAAC"}
|
package/dist/values.d.ts
CHANGED
|
@@ -1,22 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config values (`AddBlockInput.config`, `ConfigureBlock` patches) are plain
|
|
3
|
+
* JSON by default. Two sentinel object shapes emit non-literal TypeScript:
|
|
4
|
+
* {@link DataTypeValue} for a DataType instance and {@link ExprValue} for a raw
|
|
5
|
+
* expression. Anywhere a catalog field is marked `x-dataType`, pass a
|
|
6
|
+
* {@link DataTypeValue} — not a raw `$expr`.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* A value of a block's configuration: plain data, never a function or a class
|
|
10
|
+
* instance. `undefined` stands for an absent member, which the builder skips
|
|
11
|
+
* when it writes. The sentinel objects {@link DataTypeValue}, {@link ExprValue},
|
|
12
|
+
* {@link RefValue} and {@link BlockValue} are {@link ConfigObject}s.
|
|
13
|
+
*/
|
|
1
14
|
export type ConfigValue = string | number | boolean | null | undefined | ConfigValue[] | ConfigObject;
|
|
15
|
+
/** An object of {@link ConfigValue}s: a block's options, or a child's metadata. */
|
|
2
16
|
export interface ConfigObject {
|
|
3
17
|
[key: string]: ConfigValue;
|
|
4
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* A DataType value for a Form field's `type` (or a TableView `Column` `type`).
|
|
21
|
+
* Emitted as `new <DataType>(<config>)` with the import auto-added.
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* { $dataType: "string", config: { placeholder: "Name" } }
|
|
25
|
+
* // → type: new DefaultDataTypes.StringType({ placeholder: "Name" })
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
5
28
|
export type DataTypeValue = {
|
|
29
|
+
/** A `DataTypeDescriptor.id` from the catalog, e.g. `"string"` | `"select"`. */
|
|
6
30
|
$dataType: string;
|
|
31
|
+
/** The DataType's options; omit for a no-arg `new <DataType>()`. */
|
|
7
32
|
config?: ConfigObject;
|
|
8
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* A raw TypeScript expression, emitted verbatim. Required for values the builder
|
|
36
|
+
* cannot model structurally. The referenced symbol must already be importable in
|
|
37
|
+
* the target file; the builder does not add its import.
|
|
38
|
+
*
|
|
39
|
+
* Note: dms-ai's safe mode rejects `$expr` (arbitrary code defeats the
|
|
40
|
+
* structured guarantees). Only a direct file edit (vibe mode) should use it.
|
|
41
|
+
*/
|
|
9
42
|
export type ExprValue = {
|
|
10
43
|
$expr: string;
|
|
11
44
|
};
|
|
45
|
+
/**
|
|
46
|
+
* A reference to a builder-generated resource class, emitted as the bare class
|
|
47
|
+
* identifier with its import auto-added. The structured, validated alternative to
|
|
48
|
+
* `$expr` for a class reference — e.g. a `RelationType`'s `dataApiController`.
|
|
49
|
+
*
|
|
50
|
+
* ```ts
|
|
51
|
+
* { $ref: { resource: "product" } }
|
|
52
|
+
* // → productDataAPI (imported from the resource's data-api.ts)
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* `as` selects which of the resource's classes: `"dataApi"` (default, the
|
|
56
|
+
* `DataController`), `"table"` (the `Table`), or `"model"` (the `BasicDataModel`).
|
|
57
|
+
* The resource must exist (unknown → `invalid_config`). Unlike `$expr`, this is
|
|
58
|
+
* **allowed in safe mode**.
|
|
59
|
+
*/
|
|
12
60
|
export type RefValue = {
|
|
13
61
|
$ref: {
|
|
62
|
+
/** A `ResourceRef` — the resource's name, e.g. `"product"`. */
|
|
14
63
|
resource: string;
|
|
64
|
+
/** Which class to reference; defaults to `"dataApi"`. */
|
|
15
65
|
as?: "dataApi" | "table" | "model";
|
|
16
66
|
};
|
|
17
67
|
};
|
|
68
|
+
/**
|
|
69
|
+
* A nested block, for the rare option that holds a component rather than data —
|
|
70
|
+
* a ChartCard's `chart`, which the catalog marks `x-component`. Emitted as the
|
|
71
|
+
* factory call with its import auto-added, and read back as this same shape.
|
|
72
|
+
*
|
|
73
|
+
* ```ts
|
|
74
|
+
* { $block: { type: "ChartArea", config: { xaxisType: "datetime" } } }
|
|
75
|
+
* // → chart: ChartArea({ xaxisType: "datetime" })
|
|
76
|
+
* ```
|
|
77
|
+
*
|
|
78
|
+
* Allowed in safe mode: the type is checked against the catalog and the config
|
|
79
|
+
* is serialized the same way any other config is.
|
|
80
|
+
*/
|
|
18
81
|
export type BlockValue = {
|
|
19
82
|
$block: {
|
|
83
|
+
/** A `BlockTypeDescriptor.type` from the catalog. */
|
|
20
84
|
type: string;
|
|
21
85
|
config?: ConfigObject;
|
|
22
86
|
};
|
package/dist/values.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Config values (`AddBlockInput.config`, `ConfigureBlock` patches) are plain
|
|
4
|
+
* JSON by default. Two sentinel object shapes emit non-literal TypeScript:
|
|
5
|
+
* {@link DataTypeValue} for a DataType instance and {@link ExprValue} for a raw
|
|
6
|
+
* expression. Anywhere a catalog field is marked `x-dataType`, pass a
|
|
7
|
+
* {@link DataTypeValue} — not a raw `$expr`.
|
|
8
|
+
*/
|
|
2
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
10
|
//# sourceMappingURL=values.js.map
|
package/dist/values.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"values.js","sourceRoot":"","sources":["../src/values.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"values.js","sourceRoot":"","sources":["../src/values.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG"}
|
package/docs/1.introduction.md
CHANGED
|
@@ -81,3 +81,6 @@ Hand-written declarations stay editable when the builder recognizes their shape.
|
|
|
81
81
|
- [Results and errors](./8.results-and-errors.md) branches on `OpResult`, reads diagnostics, and makes a write conditional.
|
|
82
82
|
- [Drafts and preview](./9.drafts-and-preview.md) writes the blocks of a page and the data they read in one transaction, and previews either.
|
|
83
83
|
- [A chart without code](./10.a-chart-without-code.md) follows one chart from the choice of a measure to the reopened page.
|
|
84
|
+
- [Theme and branding](./11.theme-and-branding.md) reads and writes a project's colors, corners, font and logos, and gives it the layer they live in.
|
|
85
|
+
- [External databases](./11.external-databases.md) wires a database the project does not own, analyses its catalog and maps its relations.
|
|
86
|
+
- [Connect a database](./12.connect-a-database.md) checks a database live, reads the project's database state, and edits, repairs or removes a connection.
|
|
@@ -6,7 +6,7 @@ mode: tutorial
|
|
|
6
6
|
|
|
7
7
|
In this tutorial we save a revenue chart grouped by month without writing its data route by hand. We follow the interface calls that the visual builder makes when someone picks a table, a measure and a grouping. The calls run inside a project, so this page is not a standalone script.
|
|
8
8
|
|
|
9
|
-

|
|
9
|
+

|
|
10
10
|
|
|
11
11
|
Before we start, we need an existing `/shop/board` page and an `order` resource with a numeric `amount` field, a date `createdAt` field and a `status` field. Run the calls inside a project that loads the builder. Use a disposable page for the save step, because its draft replaces the page's existing blocks.
|
|
12
12
|
|
|
@@ -132,17 +132,17 @@ A route on the page, guarded with the page's own permission:
|
|
|
132
132
|
async revenueChart(
|
|
133
133
|
@AuthUserWithPermission(BoardPage) _user: User,
|
|
134
134
|
@Model(OrderModel) model: OrderModel,
|
|
135
|
-
@Parameter("from", "query") from: string,
|
|
136
|
-
@Parameter("to", "query") to: string,
|
|
137
|
-
@Parameter("compareFrom", "query") compareFrom: string,
|
|
138
|
-
@Parameter("compareTo", "query") compareTo: string,
|
|
135
|
+
@Parameter("from", "query") from: string | true | undefined,
|
|
136
|
+
@Parameter("to", "query") to: string | true | undefined,
|
|
137
|
+
@Parameter("compareFrom", "query") compareFrom: string | true | undefined,
|
|
138
|
+
@Parameter("compareTo", "query") compareTo: string | true | undefined,
|
|
139
139
|
): Promise<ChartCardData> {
|
|
140
140
|
return chartCardData(
|
|
141
|
-
await model.revenueChart(new Date(from), new Date(to)),
|
|
141
|
+
await model.revenueChart(new Date(String(from)), new Date(String(to))),
|
|
142
142
|
{
|
|
143
143
|
measure: "sum",
|
|
144
144
|
label: "Amount",
|
|
145
|
-
previous: await model.revenueChart(new Date(compareFrom), new Date(compareTo)),
|
|
145
|
+
previous: await model.revenueChart(new Date(String(compareFrom)), new Date(String(compareTo))),
|
|
146
146
|
},
|
|
147
147
|
);
|
|
148
148
|
}
|
|
@@ -6,7 +6,7 @@ mode: reference
|
|
|
6
6
|
|
|
7
7
|
## Overview
|
|
8
8
|
|
|
9
|
-
A DMS project can show pages over a database it does not own, such as a client's PostgreSQL, MongoDB or RethinkDB database. The engine's module (`@antelopejs/postgres`, `@antelopejs/mongodb` or `@antelopejs/rethinkdb`) reads and writes it live, in external mode. The builder takes such a database in four operations:
|
|
9
|
+
A DMS project can show pages over a database it does not own, such as a client's PostgreSQL, MySQL or MariaDB, MongoDB or RethinkDB database. The engine's module (`@antelopejs/postgres`, `@antelopejs/mysql`, `@antelopejs/mongodb` or `@antelopejs/rethinkdb`) reads and writes it live, in external mode. The builder takes such a database in four operations:
|
|
10
10
|
|
|
11
11
|
1. `ConfigureProject` wires the database into `antelope.config.ts`. It adds the provider module, a local module for the tables, the builder's catalog connection, and the DMS module's pin to the project's own database.
|
|
12
12
|
2. `AnalyseDatabase` reads the catalog and proposes a mapping by fixed rules. It writes nothing.
|
|
@@ -34,6 +34,7 @@ The provider's entry depends on its engine:
|
|
|
34
34
|
| Engine | Package | `env` | `disabledExports` |
|
|
35
35
|
| --- | --- | --- | --- |
|
|
36
36
|
| PostgreSQL | `@antelopejs/postgres` | `url` | none |
|
|
37
|
+
| MySQL and MariaDB | `@antelopejs/mysql` | `url`, with the database as its path | none |
|
|
37
38
|
| MongoDB | `@antelopejs/mongodb` | `url` and `database` | `@antelopejs/interface-mongodb` |
|
|
38
39
|
| RethinkDB | `@antelopejs/rethinkdb` | `url`, with the database as its path | `@antelopejs/interface-rethinkdb` |
|
|
39
40
|
|
|
@@ -69,12 +70,12 @@ const result = await ConfigureProject([
|
|
|
69
70
|
{
|
|
70
71
|
op: "ConfigureModule",
|
|
71
72
|
id: "dms",
|
|
72
|
-
entry: {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
73
|
+
entry: {
|
|
74
|
+
importOverrides: [
|
|
75
|
+
{ interface: "@antelopejs/interface-database", source: "mongodb" },
|
|
76
|
+
{ interface: catalog, source: "postgres-erp", id: "erp" },
|
|
77
|
+
],
|
|
78
|
+
},
|
|
78
79
|
},
|
|
79
80
|
]);
|
|
80
81
|
if (!result.ok) console.error(result.error);
|
|
@@ -82,19 +83,19 @@ if (!result.ok) console.error(result.error);
|
|
|
82
83
|
|
|
83
84
|
- The provider's `exportPriority` of `-1` keeps the project's own database the default for every module that does not pin `interface-database`.
|
|
84
85
|
- The tables module pins `interface-database` to the provider, and it uses the DMS. Core passes that pin on to the DMS, which every other module reaches with the default. The DMS therefore pins the project's own database to settle it. A DMS that already pins `interface-database` needs nothing more.
|
|
85
|
-
-
|
|
86
|
+
- The builder runs in the DMS, so the catalog connection is declared on the DMS's entry, `dms` here. `GetDatabaseProject` answers that id as `self`.
|
|
86
87
|
|
|
87
88
|
The connection exists once the project restarts with the variable set.
|
|
88
89
|
|
|
89
90
|
### Remove a connection
|
|
90
91
|
|
|
91
|
-
|
|
92
|
+
`RemoveDatabaseConnection(connection, { dryRun? })` takes a connection out of the configuration with `RemoveConnection` for its catalog connections and `RemoveModule` for its tables module. The tables module's folder is deleted with it. The database itself is untouched.
|
|
92
93
|
|
|
93
94
|
The tables module is the one whose `dmsBuilder.database` record names the connection. `CreateLocalModule` writes that record from `connection`. The single-operation `CreateLocalModule` takes it in its options. A module that reads through the provider without such a record is never removed or deleted.
|
|
94
95
|
|
|
95
96
|
The provider is removed too, with the variables that supply its configuration in `envOverrides`, `.env` and `.env.example`, only when it was added for this connection alone. That holds when its `exportPriority` for `@antelopejs/interface-database` is below the project's own database, and no module or connection that the removal leaves names it. Otherwise the provider stays, since it may be the project's own database.
|
|
96
97
|
|
|
97
|
-
A removal is all or nothing.
|
|
98
|
+
A removal is all or nothing. It moves the folders aside and edits `.env` first, and puts both back when the configuration cannot be written.
|
|
98
99
|
|
|
99
100
|
## Analyse a database
|
|
100
101
|
|
|
@@ -112,7 +113,7 @@ if (started.ok) {
|
|
|
112
113
|
}
|
|
113
114
|
```
|
|
114
115
|
|
|
115
|
-
- `connection` must be a catalog connection on the
|
|
116
|
+
- `connection` must be a catalog connection on the DMS's entry, and `module` a local module other than the project's own. Otherwise the call fails with `invalid_config`.
|
|
116
117
|
- One job runs per connection. Starting another while one runs answers the running one.
|
|
117
118
|
- A finished job is kept until the next one on its connection, or until a restart.
|
|
118
119
|
- Relations that the module has mapped, or recorded as excluded, are not proposed again.
|
|
@@ -221,9 +222,13 @@ if (!result.ok) console.error(result.error);
|
|
|
221
222
|
```
|
|
222
223
|
|
|
223
224
|
- **In a mapped module**, `CreateResource`, `AddField` and a `ConfigureField` that changes `dbField` fail with `invalid_config`, since the module's tables belong to the database. `DeleteResource` keeps the client's rows and warns `data_kept`.
|
|
225
|
+
- **A read-only connection** gets no write path. The access is `config.externalConnections.<connection>.access` on the `dms-database` entry of `antelope.config.ts`, loaded before every call with core's own `ConfigLoader` for the launch environment, as `dms-database` receives it: the entry, that environment's member of `environments`, `antelope.dms-database.json` and `envOverrides`, merged in core's order. It is `"read-write"` only when that says so, and a configuration that cannot be loaded counts as `"read"`. Otherwise `MapResources` and `PreviewMapResources` refuse a resource with `writable: true` and a TableView, `AddBlock`, `ComposePage` and `SetPageBlocks` refuse a `ResourceForm` in `new` or `edit` mode over one of its tables and a block over one of its tables that still serves write routes, `ConfigureBlock` and `SetPageBlocks` refuse to turn a `ResourceForm` over one into one in `new` or `edit` mode, and `ConfigureResource` refuses write routes on one. Each fails with `invalid_config`, names the connection, the place that keeps it read-only and how to allow changes, and writes nothing.
|
|
226
|
+
- **A mapped table's write routes follow the access at runtime.** Each data controller a mapping writes carries `@ExternalConnection("<connection>")`, so its `new`, `edit`, `delete`, `archive` and `restore` routes answer 403 while `dms-database` reports the connection's access as `"read"`, routes kept from a mapping made while it was `"read-write"` included, and whichever form or client posts to them.
|
|
227
|
+
- **The interface is the owner path for an access.** `ConfigureProject`, `AddModule`, `ConfigureModule` and `CreateLocalModule` write `config.externalConnections.<connection>.access` as asked: owner-authenticated routes grant `"read-write"` through them, the `dms-database` route `PUT /api/database/connections/<id>/access` and the assistant's `POST /database/project`. Agents reach them only through the MCP tool `builder_configure_project`, which refuses a step that raises an access.
|
|
224
228
|
|
|
225
229
|
## Next steps
|
|
226
230
|
|
|
231
|
+
- [Connect a database](./12.connect-a-database.md) lists the operations a connect flow drives: the live check, the project's database state, the repair and the connection's details.
|
|
227
232
|
- [Resources](./5.resources.md) describes the resources a mapping writes. They are ordinary resources, read the same way.
|
|
228
233
|
- [Queries](./6.queries.md) shows how stats over a mapped relation name it by its ref.
|
|
229
234
|
- [Results and errors](./8.results-and-errors.md) shows how to branch on what every operation answers.
|