@antelopejs/interface-dms-builder 0.3.1 → 0.4.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 +17 -17
- package/dist/catalog.d.ts +7 -7
- package/dist/drafts.d.ts +10 -9
- package/dist/drafts.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/operation-map.d.ts +66 -0
- package/dist/operation-map.js +57 -0
- package/dist/operation-map.js.map +1 -0
- package/dist/operations.d.ts +6 -5
- package/dist/operations.js.map +1 -1
- package/dist/project.d.ts +3 -2
- package/dist/project.js.map +1 -1
- package/dist/queries.d.ts +12 -11
- package/dist/resources.d.ts +3 -3
- package/dist/results.d.ts +4 -4
- package/dist/structure.d.ts +5 -4
- package/dist/values.d.ts +14 -10
- package/docs/1.introduction.md +28 -22
- package/docs/10.a-chart-without-code.md +47 -71
- package/docs/11.external-databases.md +93 -70
- package/docs/2.addressing-and-structure.md +48 -40
- package/docs/3.catalog.md +105 -49
- package/docs/4.page-operations.md +74 -60
- package/docs/5.resources.md +97 -71
- package/docs/6.queries.md +94 -95
- package/docs/7.values.md +38 -32
- package/docs/8.results-and-errors.md +62 -45
- package/docs/9.drafts-and-preview.md +84 -48
- package/docs/images/captures/editor-selected.webp +0 -0
- package/docs/tsconfig.json +4 -0
- package/package.json +2 -2
- package/docs/images/editor-selected.png +0 -0
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
title: "Addressing and structure"
|
|
3
|
+
description: "The refs that name a page, a block and a category, and the page, block and listing shapes the builder reads back."
|
|
4
|
+
mode: reference
|
|
5
|
+
---
|
|
2
6
|
|
|
3
7
|
## Overview
|
|
4
8
|
|
|
5
9
|
Every builder operation identifies its target with a string ref. This page covers `PageRef` for a page, `BlockPath` for a block inside it, and `CategoryRef` for a menu category. [Resources](./5.resources.md) and [Queries](./6.queries.md) define their own refs.
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
This page also describes the shapes the builder reads back. Those are the page metadata it can read and patch, the block tree it resolves from source, and the summaries the listing operations return. [Page operations](./4.page-operations.md) documents the operations that produce and take these shapes.
|
|
8
12
|
|
|
9
13
|
```typescript
|
|
10
14
|
import type {
|
|
@@ -18,9 +22,9 @@ const block: BlockPath = "/dashboard#kpis/row/revenue";
|
|
|
18
22
|
const category: CategoryRef = "pages.reports";
|
|
19
23
|
```
|
|
20
24
|
|
|
21
|
-
## Address a
|
|
25
|
+
## Address a page
|
|
22
26
|
|
|
23
|
-
`PageRef` is
|
|
27
|
+
`PageRef` is the route string of a page. The builder joins the slug of the category with the page's own `urlSlug`, which defaults to its name. A page named `revenue` under the root `pages` category is `/revenue`. `CreatePage` returns the ref it assigned, and every page operation takes it as its first argument.
|
|
24
28
|
|
|
25
29
|
```typescript
|
|
26
30
|
import {
|
|
@@ -38,9 +42,9 @@ if (created.ok) {
|
|
|
38
42
|
}
|
|
39
43
|
```
|
|
40
44
|
|
|
41
|
-
## Address a
|
|
45
|
+
## Address a block
|
|
42
46
|
|
|
43
|
-
`BlockPath` addresses one block inside a page
|
|
47
|
+
`BlockPath` addresses one block inside a page. A top-level block is `<pageRef>#<name>`, and each nesting level below it adds `/<childId>`.
|
|
44
48
|
|
|
45
49
|
| Path | What it addresses |
|
|
46
50
|
| --- | --- |
|
|
@@ -48,11 +52,11 @@ if (created.ok) {
|
|
|
48
52
|
| `/dashboard#kpis/row` | The `.child("row", …)` of that block |
|
|
49
53
|
| `/dashboard#kpis/row/revenue` | The `.child("revenue", …)` of `row` |
|
|
50
54
|
|
|
51
|
-
The first segment after `#` is the static class member the block
|
|
55
|
+
The first segment after `#` is the static class member that declares the block. Every further segment is the id passed to `.child()`. `AddBlock` returns the path of the block it added.
|
|
52
56
|
|
|
53
|
-
## Address a
|
|
57
|
+
## Address a category
|
|
54
58
|
|
|
55
|
-
`CategoryRef` is
|
|
59
|
+
`CategoryRef` is the stable id of a category. The three roots are `pages`, `modules` and `settings`. The ref of a category under a parent joins the parent ref and the category id with a dot, so a `reports` category under `pages` is `pages.reports`. The root category of a module is `modules.<moduleId>`.
|
|
56
60
|
|
|
57
61
|
```typescript
|
|
58
62
|
import { CreateCategory } from "@antelopejs/interface-dms-builder";
|
|
@@ -65,27 +69,27 @@ const category = await CreateCategory({
|
|
|
65
69
|
// category.data.ref === "pages.reports"
|
|
66
70
|
```
|
|
67
71
|
|
|
68
|
-
## Read a
|
|
72
|
+
## Read a page's metadata
|
|
69
73
|
|
|
70
|
-
`PageMeta`
|
|
74
|
+
`PageMeta` holds what the builder knows about a page. It comes back inside the `PageStructure` that `GetPageStructure` returns.
|
|
71
75
|
|
|
72
76
|
| Field | Type | Description |
|
|
73
77
|
| --- | --- | --- |
|
|
74
78
|
| `ref` | `PageRef` | The page's route string. |
|
|
75
79
|
| `id` | `string` | The page id, the first argument of its `PageController`. |
|
|
76
80
|
| `displayName` | `string` | The label shown in the menu. |
|
|
77
|
-
| `icon` | `string` |
|
|
81
|
+
| `icon` | `string` | The icon name, when the page declares one. |
|
|
78
82
|
| `category` | `CategoryRef` | The category the page belongs to. |
|
|
79
83
|
| `order` | `number` | Sort order within the category. |
|
|
80
84
|
| `description` | `string` | The page's description. |
|
|
81
85
|
| `hidden` | `boolean` | Whether the page is hidden from the menu. |
|
|
82
86
|
| `permission` | `PagePermission` | The permission guarding the page. |
|
|
83
|
-
| `live` | `PageLive` | The
|
|
84
|
-
| `filepath` | `string` | The file the page
|
|
87
|
+
| `live` | `PageLive` | The Direct and Pause options of the page, when it is live. |
|
|
88
|
+
| `filepath` | `string` | The file that declares the page. The builder's source index resolves it, not the runtime registry. |
|
|
85
89
|
|
|
86
|
-
`hidden`, `permission` and `live` read back like any other field
|
|
90
|
+
`hidden`, `permission` and `live` read back like any other field when the page declares them as literals. A `permission` built from a call or a reference, such as an `Action`, reads back as `undefined`. The builder reports only what it can also rewrite.
|
|
87
91
|
|
|
88
|
-
`PagePermission` mirrors the DMS `MenuOptions.permission
|
|
92
|
+
`PagePermission` mirrors the DMS `MenuOptions.permission`. It is a partial permission spec with the fields `id`, `title`, `icon`, `description`, `dependencies` and `defaultGranted`. Its type is `ConfigObject`, an object of plain data, so the compiler refuses a function or a class instance. A bare action id is not accepted. The DMS types the option as `Partial<Permission> | Action`, so the builder would write a string and the typecheck gate would then refuse it.
|
|
89
93
|
|
|
90
94
|
```typescript
|
|
91
95
|
import type { PagePermission } from "@antelopejs/interface-dms-builder";
|
|
@@ -96,15 +100,15 @@ const permission: PagePermission = {
|
|
|
96
100
|
};
|
|
97
101
|
```
|
|
98
102
|
|
|
99
|
-
The DMS also accepts an `Action` there.
|
|
103
|
+
The DMS also accepts an `Action` there. An `Action` is a live object and not data, so the builder has no encoding for it. A page that declares one reads its permission back as `undefined`.
|
|
100
104
|
|
|
101
|
-
`PageLive` mirrors the DMS `MenuOptions.live
|
|
105
|
+
`PageLive` mirrors the DMS `MenuOptions.live`, with the fields `maxRate`, `slowRateAfter` and `rememberKey`. It is a `ConfigObject` as well. When `live` is present, even as `{}`, the page is live. Its blocks then refetch through a Direct and Pause valve that its `LiveToggle` switches. When `live` is absent, the blocks refetch on every event. A patch that sends `live` as `null` removes it.
|
|
102
106
|
|
|
103
|
-
## Patch a
|
|
107
|
+
## Patch a page's metadata
|
|
104
108
|
|
|
105
|
-
`EditablePageMeta` is the subset of `PageMeta` that `ConfigurePage` accepts as a patch
|
|
109
|
+
`EditablePageMeta` is the subset of `PageMeta` that `ConfigurePage` accepts as a patch. Its fields are `displayName`, `icon`, `category`, `order`, `description`, `hidden`, `permission` and `live`. `ref`, `id` and `filepath` are not patchable, because they follow from where the page lives.
|
|
106
110
|
|
|
107
|
-
|
|
111
|
+
A patch of `category` moves the page and changes its `ref`. The result carries the new ref, and a `route_changed` warning names the old route. [Move a page between categories](./4.page-operations.md#move-a-page-between-categories) describes the move.
|
|
108
112
|
|
|
109
113
|
```typescript
|
|
110
114
|
import type { EditablePageMeta } from "@antelopejs/interface-dms-builder";
|
|
@@ -115,24 +119,25 @@ const patch: Partial<EditablePageMeta> = {
|
|
|
115
119
|
};
|
|
116
120
|
```
|
|
117
121
|
|
|
118
|
-
## Read the
|
|
122
|
+
## Read the block tree
|
|
119
123
|
|
|
120
|
-
`BlockNode` is one block in a page
|
|
124
|
+
`BlockNode` is one block in the tree of a page. The builder resolves each static member and each `.child()` call it can parse. A block it cannot parse still appears as a node, marked not editable.
|
|
121
125
|
|
|
122
126
|
| Field | Type | Description |
|
|
123
127
|
| --- | --- | --- |
|
|
124
128
|
| `path` | `BlockPath` | The block's address. |
|
|
125
129
|
| `name` | `string` | Static key for a top-level block, `.child()` id for a nested one. |
|
|
126
130
|
| `type` | `string \| null` | The factory name, or `null` when it does not resolve. |
|
|
127
|
-
| `editable` | `boolean` | `false` marks an opaque
|
|
131
|
+
| `editable` | `boolean` | Whether the builder can edit the options it understands. `false` marks an opaque block. |
|
|
128
132
|
| `opaqueReason` | `string` | Why the block is opaque. Set when `editable === false`. |
|
|
129
133
|
| `slot` | `string` | The slot the block sits in, when its parent declares slots. |
|
|
130
|
-
| `meta` | `
|
|
131
|
-
| `config` | `
|
|
132
|
-
| `
|
|
134
|
+
| `meta` | `ConfigObject` | Child metadata beyond `slot`, as declared in the third argument of `.child()`, such as `{ colSpan: 2 }`. Nested blocks only. Keep it when you build a draft from the tree. |
|
|
135
|
+
| `config` | `ConfigObject` | The options of the block that are literals. Present only when the block is editable. |
|
|
136
|
+
| `lockedOptions` | `Record<string, string>` | The top-level options defined by an expression in code, each with the reason it is locked. A save keeps them unchanged. |
|
|
137
|
+
| `controller` | `ResourceRef` | For a block whose factory takes a controller first, such as `TableView`, the resource that the leading argument resolves to, when it is a known generated resource. |
|
|
133
138
|
| `children` | `BlockNode[]` | Container blocks only, in `.child()` order. |
|
|
134
139
|
|
|
135
|
-
|
|
140
|
+
The builder can read an opaque block but cannot rewrite it. A block behind an unresolved reference is opaque, and so is a block that a computed expression produces instead of a direct factory call. `ConfigureBlock` on it, `AddBlock` under it and `MoveBlock` onto it fail with `opaque_target`, which [Results and errors](./8.results-and-errors.md) describes.
|
|
136
141
|
|
|
137
142
|
```typescript
|
|
138
143
|
import { GetPageStructure } from "@antelopejs/interface-dms-builder";
|
|
@@ -147,22 +152,22 @@ if (result.ok) {
|
|
|
147
152
|
}
|
|
148
153
|
```
|
|
149
154
|
|
|
150
|
-
## Read a
|
|
155
|
+
## Read a page's structure
|
|
151
156
|
|
|
152
157
|
`PageStructure` is the whole page as the builder sees it.
|
|
153
158
|
|
|
154
159
|
| Field | Type | Description |
|
|
155
160
|
| --- | --- | --- |
|
|
156
|
-
| `page` | `PageMeta` | The page
|
|
161
|
+
| `page` | `PageMeta` | The metadata of the page. |
|
|
157
162
|
| `blocks` | `BlockNode[]` | The top-level blocks, each carrying its own children. |
|
|
158
|
-
| `queries` | `QueryStructure[]` | The query routes declared on the page, found by shape.
|
|
163
|
+
| `queries` | `QueryStructure[]` | The query routes declared on the page, found by shape. [Queries](./6.queries.md) describes them. |
|
|
159
164
|
| `version` | `string` | A content hash of the page file. |
|
|
160
165
|
|
|
161
|
-
`version`
|
|
166
|
+
`version` makes a write conditional. Pass it back as `expectedVersion` on the next mutation, and the operation fails with `stale` if the file changed in between. [Results and errors](./8.results-and-errors.md) describes `stale`.
|
|
162
167
|
|
|
163
|
-
## Read the
|
|
168
|
+
## Read the listings
|
|
164
169
|
|
|
165
|
-
`ListPages` and `ListCategories` return summaries
|
|
170
|
+
`ListPages` and `ListCategories` return summaries instead of full structures, so a caller can survey a project without the structure of every page.
|
|
166
171
|
|
|
167
172
|
`PageSummary`:
|
|
168
173
|
|
|
@@ -172,11 +177,12 @@ if (result.ok) {
|
|
|
172
177
|
| `id` | `string` | The page id. |
|
|
173
178
|
| `displayName` | `string` | The label shown in the menu. |
|
|
174
179
|
| `category` | `CategoryRef` | The category the page belongs to. |
|
|
175
|
-
| `moduleId` | `string` | The module the page
|
|
180
|
+
| `moduleId` | `string` | The `module` option of the page, for a page that declares one. |
|
|
176
181
|
| `filepath` | `string` | The file the page is declared in. |
|
|
177
182
|
| `icon` | `string` | The icon the menu shows beside the page, when it declares one. |
|
|
178
183
|
| `order` | `number` | Sorts the page among the others of its category, when it declares one. |
|
|
179
|
-
| `hidden` | `boolean` | Whether the menu leaves the page out
|
|
184
|
+
| `hidden` | `boolean` | Whether the menu leaves the page out. Its route still answers. |
|
|
185
|
+
| `sourceModule` | `string` | The project module the page lives in, when it is not the project's own module. |
|
|
180
186
|
|
|
181
187
|
`CategorySummary`:
|
|
182
188
|
|
|
@@ -185,6 +191,8 @@ if (result.ok) {
|
|
|
185
191
|
| `ref` | `CategoryRef` | The category's id. |
|
|
186
192
|
| `displayName` | `string` | The label shown in the menu. |
|
|
187
193
|
| `parent` | `CategoryRef` | The parent category, absent for a root. |
|
|
194
|
+
| `icon` | `string` | The icon name, when the category declares one. |
|
|
195
|
+
| `order` | `number` | Its place among its siblings in the menu, lowest first, when the category declares one. |
|
|
188
196
|
|
|
189
197
|
```typescript
|
|
190
198
|
import {
|
|
@@ -199,9 +207,9 @@ const [pages, categories] = await Promise.all([
|
|
|
199
207
|
const rootPages = pages.filter((page) => page.category === "pages");
|
|
200
208
|
```
|
|
201
209
|
|
|
202
|
-
## Patch a
|
|
210
|
+
## Patch a category's metadata
|
|
203
211
|
|
|
204
|
-
`EditableCategoryMeta` is what `ConfigureCategory` accepts
|
|
212
|
+
`EditableCategoryMeta` is what `ConfigureCategory` accepts. Its fields are `displayName`, `parent`, `icon` and `order`. `ConfigureCategory` refuses a new `parent` with `unsupported`, because every page beneath the category would change route at once. [Configure a category](./4.page-operations.md#configure-a-category) lists the refusals.
|
|
205
213
|
|
|
206
214
|
```typescript
|
|
207
215
|
import type { EditableCategoryMeta } from "@antelopejs/interface-dms-builder";
|
|
@@ -209,6 +217,6 @@ import type { EditableCategoryMeta } from "@antelopejs/interface-dms-builder";
|
|
|
209
217
|
const patch: Partial<EditableCategoryMeta> = { displayName: "Reports", order: 2 };
|
|
210
218
|
```
|
|
211
219
|
|
|
212
|
-
## Next
|
|
220
|
+
## Next steps
|
|
213
221
|
|
|
214
|
-
- [Catalog](./3.catalog.md)
|
|
222
|
+
- [Catalog](./3.catalog.md) lists the block types and DataTypes the builder can write.
|
package/docs/3.catalog.md
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
title: "Catalog"
|
|
3
|
+
description: "The block types, DataTypes, reserved field names and declared data sources the builder reports, with the schema of each option."
|
|
4
|
+
mode: reference
|
|
5
|
+
---
|
|
2
6
|
|
|
3
7
|
## Overview
|
|
4
8
|
|
|
5
|
-
The catalog
|
|
9
|
+
The catalog lists what the builder can put on a page. `GetCatalog` returns a `BlockCatalog` with every block factory the builder can write, every DataType a form field can use, and the field names a resource may not take. Each entry carries the import the emitter adds and a schema for the options the factory accepts, so a caller can validate a configuration before it writes one.
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
The `type` passed to `AddBlock` is a catalog key. `AddBlock` fails with `unsupported` for a type the catalog does not list.
|
|
8
12
|
|
|
9
|
-
## Read the
|
|
13
|
+
## Read the catalog
|
|
10
14
|
|
|
11
15
|
```typescript
|
|
12
16
|
import { GetCatalog } from "@antelopejs/interface-dms-builder";
|
|
@@ -17,57 +21,76 @@ const containers = catalog.blocks.filter((block) => block.container);
|
|
|
17
21
|
const dataTypeIds = catalog.dataTypes.map((dataType) => dataType.id);
|
|
18
22
|
```
|
|
19
23
|
|
|
20
|
-
`GetCatalog` is a read
|
|
24
|
+
`GetCatalog` is a read. It returns a `BlockCatalog` directly, not an `OpResult`.
|
|
21
25
|
|
|
22
26
|
| Field | Type | Description |
|
|
23
27
|
| --- | --- | --- |
|
|
24
|
-
| `blocks` | `BlockTypeDescriptor[]` | Every block factory the builder can
|
|
28
|
+
| `blocks` | `BlockTypeDescriptor[]` | Every block factory the builder can write and configure. |
|
|
25
29
|
| `dataTypes` | `DataTypeDescriptor[]` | Every DataType usable as a form field's `type`. |
|
|
26
30
|
| `reservedFieldNames` | `string[]` | Names a resource field may not take. |
|
|
27
|
-
| `generatedAt` | `string` |
|
|
31
|
+
| `generatedAt` | `string` | The ISO time at which the builder built the cached catalog. It is also the cache key. |
|
|
28
32
|
|
|
29
|
-
The
|
|
33
|
+
The builder caches the catalog. `RefreshSourceIndex` without a `page` in its scope drops that cache, as [Refresh the source index](./4.page-operations.md#refresh-the-source-index) describes.
|
|
30
34
|
|
|
31
|
-
## Describe a
|
|
35
|
+
## Describe a block type
|
|
32
36
|
|
|
33
|
-
`BlockTypeDescriptor` is keyed on `type`, the
|
|
37
|
+
`BlockTypeDescriptor` is keyed on `type`, the export name of the factory.
|
|
34
38
|
|
|
35
39
|
| Field | Type | Description |
|
|
36
40
|
| --- | --- | --- |
|
|
37
|
-
| `type` | `string` | The
|
|
41
|
+
| `type` | `string` | The export name of the factory, such as `KpiCard`. It is the catalog key and the value of `AddBlockInput.type`. |
|
|
38
42
|
| `import` | `ImportRef` | The import the emitter adds for the factory. |
|
|
43
|
+
| `componentName` | `string` | The frontend component the factory emits, such as `dms-kpi-card`. |
|
|
44
|
+
| `label` | `string` | The label for the palette. A consumer falls back to `type` when it is absent. |
|
|
45
|
+
| `icon` | `string` | The icon name for the palette. |
|
|
46
|
+
| `group` | `BlockGroup` | The palette section: `layout`, `content`, `data`, `visualization`, or another name a DMS declares. |
|
|
39
47
|
| `container` | `boolean` | Whether the block accepts `.child(...)`. |
|
|
40
|
-
| `
|
|
41
|
-
| `
|
|
42
|
-
| `
|
|
48
|
+
| `allowedChildren` | `string[]` | The block types accepted as children. Any type is accepted when it is absent. |
|
|
49
|
+
| `slots` | `SlotDescriptor[]` | The fixed named regions the block exposes, when it has any. |
|
|
50
|
+
| `dynamicSlots` | `DynamicSlots` | Where the block's own options name its regions, for a container such as `Tab`. |
|
|
51
|
+
| `config` | `ConfigSchema` | A description of the options object of the factory. |
|
|
52
|
+
| `defaults` | `ConfigObject` | The option values the factory applies when the caller omits them. |
|
|
53
|
+
| `childMeta` | `ConfigSchema` | The schema of the metadata a child carries, such as `{ colSpan }`. |
|
|
54
|
+
| `fixedOptions` | `ConfigObject` | The options the factory sets itself whatever the caller passes, such as the `type` of a chart. |
|
|
55
|
+
| `configOrigin` | `ConfigOrigin` | How the builder determined the shape of `config`. |
|
|
43
56
|
| `description` | `string` | A human-readable description of the block. |
|
|
44
|
-
| `controllerArg` | `boolean` | `true` when the factory takes a
|
|
45
|
-
| `initialChildren` | `BlockInitialChild[]` | The children a new block of this type starts with, as the DMS's own helper places them in code
|
|
57
|
+
| `controllerArg` | `boolean` | `true` when the factory takes a controller class as its first argument, before its options object. |
|
|
58
|
+
| `initialChildren` | `BlockInitialChild[]` | The children a new block of this type starts with, as the DMS's own helper places them in code. A `PageToolbar` starts with a `LiveToggle` and a `PeriodSelector`, with the options of `pageToolbar()`. Each child has an `id` (the child id that roles name it by), a `type` (a catalog key) and its `options`. Absent for most types. |
|
|
46
59
|
|
|
47
|
-
Only a `container` block can hold children
|
|
60
|
+
Only a `container` block can hold children. Check `container` before you pass the path of a block as `AddBlockInput.parent`.
|
|
48
61
|
|
|
49
|
-
## Place a
|
|
62
|
+
## Place a block in a slot
|
|
50
63
|
|
|
51
|
-
A container block
|
|
64
|
+
A container block can declare named regions. `SlotDescriptor` describes one fixed region.
|
|
52
65
|
|
|
53
66
|
| Field | Type | Description |
|
|
54
67
|
| --- | --- | --- |
|
|
55
68
|
| `id` | `string` | The slot id, passed as `AddBlockInput.slot`. |
|
|
69
|
+
| `label` | `string` | The name of the slot for a person. |
|
|
56
70
|
| `description` | `string` | What the slot is for. |
|
|
57
71
|
|
|
58
72
|
```typescript
|
|
59
73
|
import { GetCatalog } from "@antelopejs/interface-dms-builder";
|
|
60
74
|
|
|
61
75
|
const catalog = await GetCatalog();
|
|
62
|
-
const descriptor = catalog.blocks.find((block) => block.type === "
|
|
76
|
+
const descriptor = catalog.blocks.find((block) => block.type === "Card");
|
|
63
77
|
const slotIds = descriptor?.slots?.map((slot) => slot.id) ?? [];
|
|
78
|
+
// ["actions", "footer"]
|
|
64
79
|
```
|
|
65
80
|
|
|
66
|
-
|
|
81
|
+
Some containers take their regions from their own options instead. `Tab` names one region per entry of its `items` option. Its descriptor has no `slots` and carries `dynamicSlots` instead.
|
|
67
82
|
|
|
68
|
-
|
|
83
|
+
| Field | Type | Description |
|
|
84
|
+
| --- | --- | --- |
|
|
85
|
+
| `optionPath` | `string` | The option of the block config that lists the regions, such as `items`. |
|
|
86
|
+
| `idKey` | `string` | The key of each entry that holds the slot id, such as `slot`. |
|
|
87
|
+
| `labelKey` | `string` | The key of each entry that holds its label, such as `label`. |
|
|
88
|
+
|
|
89
|
+
## Handle a block that takes a controller
|
|
90
|
+
|
|
91
|
+
Some factories take a controller class before their options, as in `TableView(controller, options)`. Those descriptors carry `controllerArg: true`, and their `config` describes the second argument, the options object.
|
|
69
92
|
|
|
70
|
-
A block type with `controllerArg: true` requires `AddBlockInput.controller`,
|
|
93
|
+
A block type with `controllerArg: true` requires `AddBlockInput.controller`, which names the resource whose DataAPI class becomes the first argument. `AddBlock` fails with `invalid_config` when that `controller` is missing, and when a `controller` is passed for any other block type. [Add a block](./4.page-operations.md#add-a-block) covers both rules.
|
|
71
94
|
|
|
72
95
|
```typescript
|
|
73
96
|
import { GetCatalog } from "@antelopejs/interface-dms-builder";
|
|
@@ -79,17 +102,26 @@ if (tableView?.controllerArg) {
|
|
|
79
102
|
}
|
|
80
103
|
```
|
|
81
104
|
|
|
82
|
-
## Read a
|
|
105
|
+
## Read a config schema
|
|
83
106
|
|
|
84
|
-
`ConfigSchema` is a `Record<string,
|
|
107
|
+
`ConfigSchema` is a `Record<string, OptionSchema>`. It describes the options of a block or a DataType in a shape close to JSON Schema. The keys are option names. Each `OptionSchema` describes one option with these fields:
|
|
85
108
|
|
|
86
|
-
|
|
109
|
+
- `type` is one of `string`, `number`, `boolean`, `object`, `array`, `record`, `union` or `unknown`.
|
|
110
|
+
- `optional`, `nullable`, `description` and `default` describe the value.
|
|
111
|
+
- `enum` lists the values of a literal union.
|
|
112
|
+
- `properties` describes a nested object, `items` the element of an array, and `values` and `keys` a record.
|
|
113
|
+
- `oneOf` lists the branches of a union, and `discriminator` names the property that tags each branch.
|
|
114
|
+
- `prefixItems` lists the element shapes of a tuple, and `allOf` the shapes of an intersection.
|
|
115
|
+
- `truncated` is `true` when the value has more structure than the catalog describes.
|
|
116
|
+
- `ui` tells a builder UI how to present the option, with fields such as `label`, `widget`, `group` and `advanced`.
|
|
117
|
+
|
|
118
|
+
On top of these keys, the schema carries DMS extensions in the `x-` namespace.
|
|
87
119
|
|
|
88
120
|
| Key | Meaning |
|
|
89
121
|
| --- | --- |
|
|
90
|
-
| `x-dataType: true` | The value is a DataType instance (`new <DataType>(...)`), such as a Form field
|
|
91
|
-
|
|
92
|
-
|
|
122
|
+
| `x-dataType: true` | The value is a DataType instance (`new <DataType>(...)`), such as the `type` of a Form field. Pass a `DataTypeValue`, described in [Value encodings](./7.values.md). |
|
|
123
|
+
| `x-component: true` | The value holds a nested block. Most nesting goes through `.child()`, which `AddBlockInput.parent` expresses instead of config. |
|
|
124
|
+
| `x-controller: true` | The option receives the DataAPI class of a table, such as the `dataApiController` of a relation. Its value is a `$ref` to a resource. |
|
|
93
125
|
|
|
94
126
|
```typescript
|
|
95
127
|
import { GetCatalog } from "@antelopejs/interface-dms-builder";
|
|
@@ -99,39 +131,39 @@ const form = catalog.blocks.find((block) => block.type === "Form");
|
|
|
99
131
|
const fieldsOption = form?.config.fields; // schema for the `fields` option
|
|
100
132
|
```
|
|
101
133
|
|
|
102
|
-
## Resolve an
|
|
134
|
+
## Resolve an import
|
|
103
135
|
|
|
104
|
-
`ImportRef` is the import the emitter adds when it writes a factory call, a DataType
|
|
136
|
+
`ImportRef` is the import the emitter adds when it writes a factory call, a DataType instance or a class reference.
|
|
105
137
|
|
|
106
138
|
| Field | Type | Description |
|
|
107
139
|
| --- | --- | --- |
|
|
108
|
-
| `name` | `string` | The imported symbol,
|
|
140
|
+
| `name` | `string` | The imported symbol, such as `KpiCard` or `DefaultDataTypes.StringType`. |
|
|
109
141
|
| `module` | `string` | A package specifier, fixed and independent of the emitting file. |
|
|
110
|
-
| `targetFile` | `string` | An absolute path
|
|
142
|
+
| `targetFile` | `string` | An absolute path that the emitter turns into a specifier relative to the file it writes. The emitter uses it for a reference to a local class, such as a generated resource. |
|
|
111
143
|
|
|
112
|
-
|
|
144
|
+
An `ImportRef` carries one of the two. `module` names a symbol from a package, and `targetFile` points at a symbol in the project's own source.
|
|
113
145
|
|
|
114
|
-
## Know
|
|
146
|
+
## Know where a shape came from
|
|
115
147
|
|
|
116
|
-
`
|
|
148
|
+
`ConfigOrigin` is `"inferred" | "annotated"`. A `BlockTypeDescriptor` reports which one applies to its `config`.
|
|
117
149
|
|
|
118
|
-
-
|
|
119
|
-
-
|
|
150
|
+
- `annotated` means that the DMS declared the block type for the builder. Its schema carries labels, defaults and widgets. A declared block type replaces the inferred one of the same name.
|
|
151
|
+
- `inferred` means that the builder read the shape off the TypeScript signature of the factory, for a factory the DMS has not declared. A precise options interface gives a precise schema, and a wide or generic option gives a loose one.
|
|
120
152
|
|
|
121
|
-
|
|
153
|
+
An empty or shallow `config` on an `inferred` descriptor means that the builder could not describe the type further. It does not mean that the factory takes no options.
|
|
122
154
|
|
|
123
|
-
## Choose a
|
|
155
|
+
## Choose a data type
|
|
124
156
|
|
|
125
|
-
`DataTypeDescriptor` describes a DataType a form field
|
|
157
|
+
`DataTypeDescriptor` describes a DataType that the `type` of a form field or of a table column can use.
|
|
126
158
|
|
|
127
159
|
| Field | Type | Description |
|
|
128
160
|
| --- | --- | --- |
|
|
129
|
-
| `id` | `string` | The registered id,
|
|
161
|
+
| `id` | `string` | The registered id, such as `string`, `number` or `select`. |
|
|
130
162
|
| `import` | `ImportRef` | The import the emitter adds for the DataType class. |
|
|
131
|
-
| `config` | `ConfigSchema` | A description of the DataType
|
|
163
|
+
| `config` | `ConfigSchema` | A description of the options of the DataType. |
|
|
132
164
|
| `description` | `string` | A human-readable description. |
|
|
133
165
|
|
|
134
|
-
|
|
166
|
+
Pass the `id` as `$dataType` to write a DataType value, as [Value encodings](./7.values.md) describes. A `$dataType` that the catalog does not list fails with `invalid_config`.
|
|
135
167
|
|
|
136
168
|
```typescript
|
|
137
169
|
import {
|
|
@@ -158,9 +190,9 @@ await AddBlock({
|
|
|
158
190
|
});
|
|
159
191
|
```
|
|
160
192
|
|
|
161
|
-
## Avoid a
|
|
193
|
+
## Avoid a reserved field name
|
|
162
194
|
|
|
163
|
-
`reservedFieldNames` lists the names a resource field may not take
|
|
195
|
+
`reservedFieldNames` lists the names a resource field may not take. They collide with a route of the generated DataController or a member of the model, and `CreateResource` and `AddField` fail with `invalid_config` on them. The list is `_id`, `model`, `get`, `list`, `select`, `count`, `new`, `edit`, `delete`, `archive`, `restore`, `exportStart`, `exportStatus` and `exportDownload`. Read it from the catalog instead of keeping a copy.
|
|
164
196
|
|
|
165
197
|
```typescript
|
|
166
198
|
import { GetCatalog } from "@antelopejs/interface-dms-builder";
|
|
@@ -170,8 +202,32 @@ const reserved = new Set(catalog.reservedFieldNames);
|
|
|
170
202
|
const fieldName = reserved.has("status") ? "state" : "status";
|
|
171
203
|
```
|
|
172
204
|
|
|
173
|
-
|
|
205
|
+
[Resources](./5.resources.md) covers resource fields.
|
|
206
|
+
|
|
207
|
+
## List the declared data sources
|
|
208
|
+
|
|
209
|
+
`ListDataSources(response?)` returns the routes that developers declared beside their own code as something a block may read. It is separate from the catalog, because these sources come and go as modules load. With `response`, it returns only the sources whose `responseKind` equals it. It returns a `DataSourceDescriptor[]` directly, not an `OpResult`.
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
import { ListDataSources } from "@antelopejs/interface-dms-builder";
|
|
213
|
+
|
|
214
|
+
const sources = await ListDataSources();
|
|
215
|
+
const paths = sources.map((source) => source.path);
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
| Field | Type | Description |
|
|
219
|
+
| --- | --- | --- |
|
|
220
|
+
| `id` | `string` | The id of the source. |
|
|
221
|
+
| `title` | `string` | The title of the source. |
|
|
222
|
+
| `description` | `string` | A description of the source. |
|
|
223
|
+
| `responseKind` | `string` | The shape the source answers with, matched against what a block can read. |
|
|
224
|
+
| `path` | `string` | The path a block fetches, as declared. |
|
|
225
|
+
| `method` | `string` | The HTTP method, when the source declares one. |
|
|
226
|
+
| `params` | `ConfigSchema` | The parameters the source takes, described like block options. |
|
|
227
|
+
| `period` | `{ from: string; to: string }` | The query parameters that carry a period, when the source takes one. |
|
|
228
|
+
|
|
229
|
+
The builder never reads or rewrites the code behind a declared source. It knows only what the declaration says.
|
|
174
230
|
|
|
175
|
-
## Next
|
|
231
|
+
## Next steps
|
|
176
232
|
|
|
177
|
-
- [Page
|
|
233
|
+
- [Page operations](./4.page-operations.md) creates pages and categories, and edits the block tree of a page.
|