@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,14 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
title: "Page operations"
|
|
3
|
+
description: "The operations that list, create, configure, move and delete pages, categories and the blocks of a page, with their inputs and refusals."
|
|
4
|
+
mode: reference
|
|
5
|
+
---
|
|
2
6
|
|
|
3
7
|
## Overview
|
|
4
8
|
|
|
5
|
-
Page operations cover
|
|
9
|
+
Page operations cover the pages, the categories that hold them, and the block tree inside each page. The reads are `ListPages`, `ListCategories` and `GetPageStructure`. The mutations, such as `CreatePage`, `AddBlock` and `MoveBlock`, rewrite the source and return the list of `FileChange` entries they wrote.
|
|
6
10
|
|
|
7
|
-
Every mutation returns an `OpResult`, so branch on `ok` before
|
|
11
|
+
Every mutation returns an `OpResult`, so branch on `ok` before you read `data`. [Addressing and structure](./2.addressing-and-structure.md) describes the refs and shapes these operations take and return. [Results and errors](./8.results-and-errors.md) describes their errors and warnings.
|
|
8
12
|
|
|
9
|
-
## List
|
|
13
|
+
## List pages and categories
|
|
10
14
|
|
|
11
|
-
`ListPages` and `ListCategories` are plain reads
|
|
15
|
+
`ListPages` and `ListCategories` are plain reads. They return arrays, not an `OpResult`.
|
|
12
16
|
|
|
13
17
|
```typescript
|
|
14
18
|
import {
|
|
@@ -24,9 +28,9 @@ for (const page of pages) {
|
|
|
24
28
|
}
|
|
25
29
|
```
|
|
26
30
|
|
|
27
|
-
## Read a
|
|
31
|
+
## Read a page's structure
|
|
28
32
|
|
|
29
|
-
`GetPageStructure(ref)` returns the
|
|
33
|
+
`GetPageStructure(ref)` returns the metadata, the block tree and the queries of the page in an `OpResult<PageStructure>`. Its `changes` array is empty, because the operation is a read.
|
|
30
34
|
|
|
31
35
|
```typescript
|
|
32
36
|
import { GetPageStructure } from "@antelopejs/interface-dms-builder";
|
|
@@ -39,11 +43,11 @@ if (!result.ok) {
|
|
|
39
43
|
const { page, blocks, queries, version } = result.data;
|
|
40
44
|
```
|
|
41
45
|
|
|
42
|
-
Keep `version
|
|
46
|
+
Keep `version`. Passed as `expectedVersion` on the next mutation, it makes the write conditional.
|
|
43
47
|
|
|
44
|
-
## Refresh the
|
|
48
|
+
## Refresh the source index
|
|
45
49
|
|
|
46
|
-
The builder keeps an index of the project's source.
|
|
50
|
+
The builder keeps an index of the project's source and a cached catalog. Every mutation drops the index after it writes. A read also rescans by itself when a file the index read has changed or disappeared since the scan, after a hand edit or a checkout for example. The index does not see a new file until a file it already read changes, such as the barrel that imports the new file. It never drops the catalog. Call `RefreshSourceIndex` after such a change, and after a change to the components the catalog describes.
|
|
47
51
|
|
|
48
52
|
```typescript
|
|
49
53
|
import { RefreshSourceIndex } from "@antelopejs/interface-dms-builder";
|
|
@@ -56,15 +60,15 @@ await RefreshSourceIndex({ page: "/dashboard" }); // source index only
|
|
|
56
60
|
|
|
57
61
|
| Option | Type | Description |
|
|
58
62
|
| --- | --- | --- |
|
|
59
|
-
| `page` | `PageRef` | Keep the cached catalog.
|
|
63
|
+
| `page` | `PageRef` | Keep the cached catalog. Without `page`, the call drops the catalog as well. |
|
|
60
64
|
|
|
61
|
-
The scope does not narrow the source index
|
|
65
|
+
The scope does not narrow the source index. The call drops the whole index either way, and a `page` only spares the catalog cache. Pass a page when the change touched page source and left the component catalog alone. It saves a rebuild of the catalog, not a rescan of the project.
|
|
62
66
|
|
|
63
|
-
|
|
67
|
+
The call only drops the caches. The next read pays the cost, because it rescans the project in full and keeps the result. Two refreshes in a row cost nothing extra, and a refresh before every read costs a full scan every time. The operation returns `void`, not an `OpResult`.
|
|
64
68
|
|
|
65
|
-
## Create a
|
|
69
|
+
## Create a page
|
|
66
70
|
|
|
67
|
-
`CreatePage(input)` writes a new page file
|
|
71
|
+
`CreatePage(input)` writes a new page file and wires it into the nearest barrel. It returns the ref it assigned and the file it created. The new page uses `DefaultLayout({ fullWidth: true })`.
|
|
68
72
|
|
|
69
73
|
```typescript
|
|
70
74
|
import { CreatePage } from "@antelopejs/interface-dms-builder";
|
|
@@ -85,16 +89,17 @@ if (result.ok) {
|
|
|
85
89
|
|
|
86
90
|
| Option | Type | Description |
|
|
87
91
|
| --- | --- | --- |
|
|
88
|
-
| `name` | `string` | The page
|
|
92
|
+
| `name` | `string` | The page id and route segment. Required. It must be lowercase letters, digits and single dashes, or the call fails with `invalid_config`. A duplicate fails with `duplicate_name`. |
|
|
89
93
|
| `displayName` | `string` | The label shown in the menu. Required. |
|
|
90
|
-
| `category` | `CategoryRef` | The category to attach to. Required
|
|
91
|
-
| `icon` | `string` |
|
|
94
|
+
| `category` | `CategoryRef` | The category to attach to. Required. An unknown category fails with `not_found`. |
|
|
95
|
+
| `icon` | `string` | The icon name. |
|
|
92
96
|
| `order` | `number` | Sort order within the category. |
|
|
93
97
|
| `description` | `string` | The page's description. |
|
|
94
98
|
| `permission` | `PagePermission` | The permission guarding the page. |
|
|
95
|
-
| `dir` | `string` |
|
|
99
|
+
| `dir` | `string` | A folder relative to the `src` root, which replaces the placement beside the category. |
|
|
100
|
+
| `module` | `string` | The project module to write into, by its id in the project configuration. Without it, the builder writes into the project's own module. The module must be a local module with an `src/index.ts`, and the page may only use declarations from that same module. A category declared in another module fails with `invalid_config`. |
|
|
96
101
|
|
|
97
|
-
Without `dir`, the page
|
|
102
|
+
Without `dir`, the page goes to `<category-folder>/<name>/page.ts` when the project's source declares the category and an `index.ts` barrel sits beside it. Otherwise it goes to `src/<name>.ts`, next to the root barrel. With `dir`, it goes to `src/<dir>/<name>/page.ts`. In each case the builder wires the nearest barrel above the file, which keeps a relative import chain up to `src/index.ts`. `dir` must stay inside the `src` tree. A `dir` that leaves it, or a project with no barrel to wire, fails with `unsupported`.
|
|
98
103
|
|
|
99
104
|
```typescript
|
|
100
105
|
import { CreatePage } from "@antelopejs/interface-dms-builder";
|
|
@@ -107,9 +112,9 @@ await CreatePage({
|
|
|
107
112
|
});
|
|
108
113
|
```
|
|
109
114
|
|
|
110
|
-
## Configure a
|
|
115
|
+
## Configure a page
|
|
111
116
|
|
|
112
|
-
`ConfigurePage(ref, patch, opts?)` patches the page
|
|
117
|
+
`ConfigurePage(ref, patch, opts?)` patches the metadata of the page in place and returns its ref. The patch is a `Partial<EditablePageMeta>`. Keys left out stay untouched, and a key set to `undefined` or `null` is removed from the options of the page. A page whose options are not a plain object literal fails with `unsupported`, because the builder needs a literal to rewrite.
|
|
113
118
|
|
|
114
119
|
```typescript
|
|
115
120
|
import { ConfigurePage } from "@antelopejs/interface-dms-builder";
|
|
@@ -121,11 +126,11 @@ const result = await ConfigurePage("/revenue", {
|
|
|
121
126
|
});
|
|
122
127
|
```
|
|
123
128
|
|
|
124
|
-
### Move a
|
|
129
|
+
### Move a page between categories
|
|
125
130
|
|
|
126
|
-
|
|
131
|
+
The category of a page decides its route, so a patch of `category` moves the page. `ConfigurePage` rewrites the `category` option and its import. When the new category has an `index.ts` barrel beside it, the builder also moves the file to the folder where `CreatePage` would have put it, and moves the registration with it, so each barrel still lists what its folder holds. The builder rewrites the relative imports inside the page for its new location.
|
|
127
132
|
|
|
128
|
-
The result carries the
|
|
133
|
+
The result carries the new `ref` of the page, and a `route_changed` warning names the old one. Nothing redirects the old route, so links and bookmarks to it break.
|
|
129
134
|
|
|
130
135
|
```typescript
|
|
131
136
|
import { ConfigurePage } from "@antelopejs/interface-dms-builder";
|
|
@@ -134,20 +139,24 @@ const moved = await ConfigurePage("/form/revenue", { category: "pages.reports" }
|
|
|
134
139
|
if (moved.ok) {
|
|
135
140
|
console.log(moved.data.ref); // "/reports/revenue"
|
|
136
141
|
for (const warning of moved.warnings ?? []) {
|
|
137
|
-
console.log(warning.code, warning.message); // "route_changed"
|
|
142
|
+
console.log(warning.code, warning.message); // "route_changed" and its message
|
|
138
143
|
}
|
|
139
144
|
}
|
|
140
145
|
```
|
|
141
146
|
|
|
142
|
-
The
|
|
147
|
+
The builder refuses the move in three cases:
|
|
148
|
+
|
|
149
|
+
- The target category is unknown. The call fails with `not_found`.
|
|
150
|
+
- The target category is built in or not declared in source, so a page cannot reference it. The call fails with `unsupported`.
|
|
151
|
+
- The destination already holds a page of that name. The call fails with `duplicate_name`.
|
|
143
152
|
|
|
144
153
|
`opts` is a `MutationOpts`, so `expectedVersion` makes the write conditional.
|
|
145
154
|
|
|
146
|
-
## Delete a
|
|
155
|
+
## Delete a page
|
|
147
156
|
|
|
148
|
-
`DeletePage(ref, opts?)` removes the page file and
|
|
157
|
+
`DeletePage(ref, opts?)` removes the page class, with the constants, imports and generated model methods that only the page used. The builder deletes the file and removes its barrel import only when nothing but imports is left in it, because a hand-written page file can also declare a category that other pages import. `opts` is a `MutationOpts`.
|
|
149
158
|
|
|
150
|
-
```typescript
|
|
159
|
+
```typescript fragment
|
|
151
160
|
import { DeletePage } from "@antelopejs/interface-dms-builder";
|
|
152
161
|
|
|
153
162
|
const result = await DeletePage("/revenue", { expectedVersion: version });
|
|
@@ -156,9 +165,9 @@ if (!result.ok && result.error.code === "stale") {
|
|
|
156
165
|
}
|
|
157
166
|
```
|
|
158
167
|
|
|
159
|
-
## Create a
|
|
168
|
+
## Create a category
|
|
160
169
|
|
|
161
|
-
`CreateCategory(input)`
|
|
170
|
+
`CreateCategory(input)` writes the new category to `<name>.category.ts` beside the root barrel and imports that file from the barrel. A project with no root barrel fails with `unsupported`.
|
|
162
171
|
|
|
163
172
|
```typescript
|
|
164
173
|
import { CreateCategory } from "@antelopejs/interface-dms-builder";
|
|
@@ -177,15 +186,16 @@ const result = await CreateCategory({
|
|
|
177
186
|
|
|
178
187
|
| Option | Type | Description |
|
|
179
188
|
| --- | --- | --- |
|
|
180
|
-
| `name` | `string` | The
|
|
189
|
+
| `name` | `string` | The id segment of the category. Required. It must be lowercase letters, digits and single dashes, or the call fails with `invalid_config`. A duplicate fails with `duplicate_name`. |
|
|
181
190
|
| `displayName` | `string` | The label shown in the menu. Required. |
|
|
182
191
|
| `parent` | `CategoryRef` | The parent category. Omit for a category under the root `pages`. |
|
|
183
|
-
| `icon` | `string` |
|
|
192
|
+
| `icon` | `string` | The icon name. |
|
|
184
193
|
| `order` | `number` | Sort order among siblings. |
|
|
194
|
+
| `module` | `string` | The project module to write into, as `CreatePageInput.module`. |
|
|
185
195
|
|
|
186
196
|
A `parent` that does not exist fails with `not_found`.
|
|
187
197
|
|
|
188
|
-
## Configure a
|
|
198
|
+
## Configure a category
|
|
189
199
|
|
|
190
200
|
`ConfigureCategory(ref, patch)` patches an existing category. It takes no options argument.
|
|
191
201
|
|
|
@@ -198,11 +208,15 @@ await ConfigureCategory("pages.reports", {
|
|
|
198
208
|
});
|
|
199
209
|
```
|
|
200
210
|
|
|
201
|
-
|
|
211
|
+
An unknown category fails with `not_found`. Three refusals fail with `unsupported`:
|
|
212
|
+
|
|
213
|
+
- a patch that carries `parent`,
|
|
214
|
+
- a category that is built in or not declared in editable source,
|
|
215
|
+
- a category whose options are not a plain object literal.
|
|
202
216
|
|
|
203
|
-
## Delete a
|
|
217
|
+
## Delete a category
|
|
204
218
|
|
|
205
|
-
`DeleteCategory(ref)` removes the category declaration
|
|
219
|
+
`DeleteCategory(ref)` removes the category declaration. When nothing but imports is left in its file, the builder deletes the file and the imports of it.
|
|
206
220
|
|
|
207
221
|
```typescript
|
|
208
222
|
import { DeleteCategory } from "@antelopejs/interface-dms-builder";
|
|
@@ -213,11 +227,11 @@ if (!result.ok && result.error.code === "referential_integrity") {
|
|
|
213
227
|
}
|
|
214
228
|
```
|
|
215
229
|
|
|
216
|
-
A category that still holds pages or child categories fails with `referential_integrity
|
|
230
|
+
A category that still holds pages, directly or through its subcategories, or that has child categories, fails with `referential_integrity`. `blockedBy` lists the refs of those pages and child categories. A built-in category, or one not declared in editable source, fails with `unsupported`.
|
|
217
231
|
|
|
218
|
-
## Add a
|
|
232
|
+
## Add a block
|
|
219
233
|
|
|
220
|
-
`AddBlock(input, opts?)`
|
|
234
|
+
`AddBlock(input, opts?)` writes a factory call into the page and returns the `BlockPath` of the new block.
|
|
221
235
|
|
|
222
236
|
```typescript
|
|
223
237
|
import { AddBlock } from "@antelopejs/interface-dms-builder";
|
|
@@ -243,18 +257,18 @@ if (result.ok) {
|
|
|
243
257
|
| `page` | `PageRef` | The page to add to. Required. |
|
|
244
258
|
| `name` | `string` | The block's name, unique among its siblings. Required. A duplicate fails with `duplicate_name`. |
|
|
245
259
|
| `type` | `string` | A `BlockTypeDescriptor.type` from the catalog. Required. An unknown type fails with `unsupported`. |
|
|
246
|
-
| `config` | `
|
|
260
|
+
| `config` | `ConfigObject` | The factory's options object. Required. |
|
|
247
261
|
| `parent` | `BlockPath` | The container to nest under. Omit to add a top-level block. |
|
|
248
262
|
| `slot` | `string` | The slot within the parent container. |
|
|
249
263
|
| `index` | `number` | Position among siblings. Defaults to appending. |
|
|
250
|
-
| `meta` | `
|
|
264
|
+
| `meta` | `ConfigObject` | Child metadata emitted alongside `slot` in the third argument of `.child()`, such as `{ colSpan: 2 }`. Ignored for top-level blocks. |
|
|
251
265
|
| `controller` | `ResourceRef` | The resource whose DataAPI class is the leading argument, for controller-leading block types. |
|
|
252
266
|
|
|
253
|
-
`config` is plain JSON by default
|
|
267
|
+
`config` is plain JSON by default. A value that is not a literal, such as a DataType instance or a reference to a generated class, uses the encodings in [Value encodings](./7.values.md).
|
|
254
268
|
|
|
255
|
-
|
|
269
|
+
A nested block needs an editable container. A `parent` that resolves to an opaque block fails with `opaque_target`, and a `parent` that does not resolve fails with `not_found`. The builder clamps an `index` out of range, and the result carries an `index_clamped` warning.
|
|
256
270
|
|
|
257
|
-
|
|
271
|
+
A block type whose catalog entry has `controllerArg: true`, such as `TableView`, requires `controller`. Any other type refuses it. Both mismatches fail with `invalid_config`.
|
|
258
272
|
|
|
259
273
|
```typescript
|
|
260
274
|
import { AddBlock } from "@antelopejs/interface-dms-builder";
|
|
@@ -268,9 +282,9 @@ await AddBlock({
|
|
|
268
282
|
});
|
|
269
283
|
```
|
|
270
284
|
|
|
271
|
-
## Configure a
|
|
285
|
+
## Configure a block
|
|
272
286
|
|
|
273
|
-
`ConfigureBlock(path, patch, opts?)` rewrites
|
|
287
|
+
`ConfigureBlock(path, patch, opts?)` rewrites the options object of a block. By default the patch merges. Listed keys are replaced, other keys stay, and a key set to `undefined` is removed.
|
|
274
288
|
|
|
275
289
|
```typescript
|
|
276
290
|
import { ConfigureBlock } from "@antelopejs/interface-dms-builder";
|
|
@@ -287,9 +301,9 @@ await ConfigureBlock("/revenue#total", {
|
|
|
287
301
|
| --- | --- | --- |
|
|
288
302
|
| `replace` | `boolean` | Replace the whole options object instead of merging into it. |
|
|
289
303
|
| `expectedVersion` | `string` | The `PageStructure.version` you last read. A mismatch fails with `stale`. |
|
|
290
|
-
| `meta` | `
|
|
304
|
+
| `meta` | `ConfigObject` | A patch of the child metadata, such as `slot` or `colSpan`. A key set to `undefined` is removed. A top-level block has no `.child()` call to carry it, so it fails with `unsupported`. |
|
|
291
305
|
|
|
292
|
-
|
|
306
|
+
The following example reads the version before it changes an existing child. `/revenue#grid/total` must already be a child of the grid of the page.
|
|
293
307
|
|
|
294
308
|
```ts docs-check
|
|
295
309
|
import { ConfigureBlock, GetPageStructure } from "@antelopejs/interface-dms-builder";
|
|
@@ -306,9 +320,9 @@ export async function resizeRevenueCard() {
|
|
|
306
320
|
}
|
|
307
321
|
```
|
|
308
322
|
|
|
309
|
-
An opaque block fails with `opaque_target
|
|
323
|
+
An opaque block fails with `opaque_target`, because the builder can read it but cannot rewrite it.
|
|
310
324
|
|
|
311
|
-
## Move a
|
|
325
|
+
## Move a block
|
|
312
326
|
|
|
313
327
|
`MoveBlock(path, dest, opts?)` moves a child block within its container or into another one.
|
|
314
328
|
|
|
@@ -325,15 +339,15 @@ await MoveBlock("/revenue#grid/row/total", {
|
|
|
325
339
|
|
|
326
340
|
| Option | Type | Description |
|
|
327
341
|
| --- | --- | --- |
|
|
328
|
-
| `parent` | `BlockPath` | The destination container. |
|
|
329
|
-
| `slot` | `string` | The
|
|
342
|
+
| `parent` | `BlockPath` | The destination container. Optional in the type, and required by the operation. |
|
|
343
|
+
| `slot` | `string` | Declared in the type, but `MoveBlock` does not read it. The block lands among the destination's children. |
|
|
330
344
|
| `index` | `number` | Position among the destination's children. Required. |
|
|
331
345
|
|
|
332
|
-
The
|
|
346
|
+
The path must address a nested block. A top-level block, or a destination without a `parent`, fails with `unsupported`. The builder clamps an `index` out of range and adds an `index_clamped` warning. An opaque destination fails with `opaque_target`, and a missing one fails with `not_found`.
|
|
333
347
|
|
|
334
|
-
## Remove a
|
|
348
|
+
## Remove a block
|
|
335
349
|
|
|
336
|
-
`RemoveBlock(path, opts?)` deletes a block.
|
|
350
|
+
`RemoveBlock(path, opts?)` deletes a block. The builder removes a top-level block as a static member, and drops a nested one from the `.child()` chain of its parent.
|
|
337
351
|
|
|
338
352
|
```typescript
|
|
339
353
|
import { RemoveBlock } from "@antelopejs/interface-dms-builder";
|
|
@@ -344,7 +358,7 @@ if (result.ok) {
|
|
|
344
358
|
}
|
|
345
359
|
```
|
|
346
360
|
|
|
347
|
-
## Next
|
|
361
|
+
## Next steps
|
|
348
362
|
|
|
349
|
-
- [Resources](./5.resources.md)
|
|
350
|
-
- [Drafts and
|
|
363
|
+
- [Resources](./5.resources.md) generates the tables and DataAPI controllers a page reads from.
|
|
364
|
+
- [Drafts and preview](./9.drafts-and-preview.md) writes the whole block tree of a page in one transaction.
|