@antelopejs/interface-dms-builder 0.2.0 → 0.2.1

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 CHANGED
@@ -1,12 +1,84 @@
1
+ <div align="center">
2
+
1
3
  # @antelopejs/interface-dms-builder
2
4
 
3
- The public interface contract for AntelopeJS DMS builder implementations.
5
+ <a href="https://www.npmjs.com/package/@antelopejs/interface-dms-builder"><img alt="npm" src="https://img.shields.io/npm/v/@antelopejs/interface-dms-builder?style=for-the-badge&labelColor=000000&color=000000"></a>
6
+ <a href="./LICENSE"><img alt="License" src="https://img.shields.io/npm/l/@antelopejs/interface-dms-builder?style=for-the-badge&labelColor=000000&color=000000"></a>
7
+ <a href="https://discord.gg/sjK28QHrA7"><img alt="Discord" src="https://img.shields.io/badge/Discord-18181B?logo=discord&style=for-the-badge&color=000000"></a>
8
+ <a href="https://dms.antelopejs.com/docs/modules/builder/extending"><img alt="Documentation" src="https://img.shields.io/badge/Docs-18181B?style=for-the-badge&color=000000"></a>
9
+
10
+ The AntelopeJS interface to edit a DMS project's pages, blocks, resources and queries from code.
11
+
12
+ </div>
13
+
14
+ ## What it does
15
+
16
+ - Creates and edits pages, categories and their block trees: `CreatePage`, `AddBlock`, `ConfigureBlock`, `MoveBlock`, `SetPageBlocks`…
17
+ - Generates resources (a `Table`, a `DataController` and a model) and edits their fields.
18
+ - Compiles query templates into a model method and a page route, so a card gets a number without hand-written code.
19
+ - Reports every block type and DataType the builder can write, with a schema for its options (`GetCatalog`).
20
+ - Returns every mutation as an `OpResult`: the files changed on success, a typed error otherwise.
21
+
22
+ Every operation is an `InterfaceFunction` routed to [`@antelopejs/dms-builder`](https://www.npmjs.com/package/@antelopejs/dms-builder), which parses the project, applies the edit as an AST rewrite, and writes only if the project still typechecks.
23
+
24
+ ## Install
25
+
26
+ Add the interface to the module that calls the builder:
27
+
28
+ ```bash
29
+ pnpm add @antelopejs/interface-dms-builder
30
+ ```
31
+
32
+ ## Quick start
33
+
34
+ Create a page and put a KPI card on it:
4
35
 
5
36
  ```ts
6
- import { GetCatalog } from "@antelopejs/interface-dms-builder";
37
+ import { AddBlock, CreatePage } from "@antelopejs/interface-dms-builder";
38
+
39
+ const page = await CreatePage({
40
+ name: "revenue",
41
+ displayName: "Revenue",
42
+ category: "pages",
43
+ icon: "i-ph-chart-line",
44
+ });
45
+ if (!page.ok) {
46
+ throw new Error(`could not create the page: ${page.error.code}`);
47
+ }
48
+
49
+ const block = await AddBlock({
50
+ page: page.data.ref,
51
+ name: "total",
52
+ type: "KpiCard",
53
+ config: { title: "Total revenue", icon: "i-ph-currency-eur" },
54
+ });
55
+ if (!block.ok) {
56
+ throw new Error(`could not add the block: ${block.error.code}`);
57
+ }
7
58
  ```
8
59
 
9
- The package contains only the interface types and `InterfaceFunction`
10
- definitions. The implementation is provided by `@antelopejs/dms-builder`.
60
+ ## Compatibility
61
+
62
+ The interface declares this peer dependency:
63
+
64
+ <!-- docs-compat: ./package.json#peerDependencies -->
65
+
66
+ | Package | Range |
67
+ | --- | --- |
68
+ | `@antelopejs/interface-core` | `>=0.2.4 <1.0.0` |
69
+
70
+ The 0.2 interface is implemented by `@antelopejs/dms-builder` 0.4, used with DMS 0.9. These implementation versions are not peer dependencies of the interface package. The implementation runs in development only, unless its [`api.enabled`](https://dms.antelopejs.com/docs/modules/builder/configuration) option forces it.
71
+
72
+ ## Documentation
73
+
74
+ - [Extending the builder](https://dms.antelopejs.com/docs/modules/builder/extending): the interface and the HTTP API
75
+ - [Interface reference](./docs/1.introduction.md): the canonical contract, shipped with this package and published at [/docs/modules/builder/reference](https://dms.antelopejs.com/docs/modules/builder/reference)
76
+ - [A chart without code](./docs/10.a-chart-without-code.md): the whole journey, from picking a measure to reopening the page
77
+
78
+ ## Contributing
79
+
80
+ This package lives in the [`AntelopeJS/dms-builder`](https://github.com/AntelopeJS/dms-builder) pnpm workspace, next to the module that implements it. Read [CONTRIBUTING.md](https://github.com/AntelopeJS/dms-builder/blob/main/CONTRIBUTING.md) and the [repository README](https://github.com/AntelopeJS/dms-builder#contributing) for the development commands. Release this package before the module that implements it.
81
+
82
+ ## License
11
83
 
12
- The contract is documented in [`docs`](./docs/1.introduction.md).
84
+ [Apache-2.0](./LICENSE)
@@ -1 +1 @@
1
- {"version":3,"file":"queries.js","sourceRoot":"","sources":["../src/queries.ts"],"names":[],"mappings":";;;AAAA,+DAA+D;AAyMlD,QAAA,kBAAkB,GAC7B,IAAA,kCAAiB,GAEd,CAAC;AAEO,QAAA,QAAQ,GACnB,IAAA,kCAAiB,GAMd,CAAC;AAEO,QAAA,cAAc,GACzB,IAAA,kCAAiB,GAMd,CAAC;AAEO,QAAA,WAAW,GACtB,IAAA,kCAAiB,GAEd,CAAC"}
1
+ {"version":3,"file":"queries.js","sourceRoot":"","sources":["../src/queries.ts"],"names":[],"mappings":";;;AAAA,+DAA+D;AA0MlD,QAAA,kBAAkB,GAC7B,IAAA,kCAAiB,GAEd,CAAC;AAEO,QAAA,QAAQ,GACnB,IAAA,kCAAiB,GAMd,CAAC;AAEO,QAAA,cAAc,GACzB,IAAA,kCAAiB,GAMd,CAAC;AAEO,QAAA,WAAW,GACtB,IAAA,kCAAiB,GAEd,CAAC"}
@@ -73,7 +73,7 @@ await SetPageBlocks("/shop/board", {
73
73
  type: "ChartCard",
74
74
  config: {
75
75
  title: "Revenue",
76
- fetchUrl: "/shop/board/stats/revenue-chart",
76
+ fetchUrl: "/dms/pages/shop/board/stats/revenue-chart",
77
77
  periodScope: "page",
78
78
  chart: {
79
79
  $block: { type: "ChartArea", config: { xaxisType: "category" } },
@@ -247,6 +247,7 @@ if (result.ok) {
247
247
  | `parent` | `BlockPath` | The container to nest under. Omit to add a top-level block. |
248
248
  | `slot` | `string` | The slot within the parent container. |
249
249
  | `index` | `number` | Position among siblings. Defaults to appending. |
250
+ | `meta` | `Record<string, unknown>` | Child metadata emitted alongside `slot` in the third argument of `.child()`, such as `{ colSpan: 2 }`. Ignored for top-level blocks. |
250
251
  | `controller` | `ResourceRef` | The resource whose DataAPI class is the leading argument, for controller-leading block types. |
251
252
 
252
253
  `config` is plain JSON by default; values that are not literals — a DataType instance, a reference to a generated class — use the sentinel encodings in [Value Encodings](./7.values.md).
@@ -286,15 +287,23 @@ await ConfigureBlock("/revenue#total", {
286
287
  | --- | --- | --- |
287
288
  | `replace` | `boolean` | Replace the whole options object instead of merging into it. |
288
289
  | `expectedVersion` | `string` | The `PageStructure.version` you last read. A mismatch fails with `stale`. |
290
+ | `meta` | `Record<string, unknown>` | Patch child metadata (`slot`, `colSpan`, …). A key set to `undefined` is removed. Rejected for a top-level block, which has no `.child()` call. |
289
291
 
290
- ```typescript
291
- import { ConfigureBlock } from "@antelopejs/interface-dms-builder";
292
+ Read the version before changing an existing child. Here `/revenue#grid/total` must already be a child of the page's grid:
293
+
294
+ ```ts docs-check
295
+ import { ConfigureBlock, GetPageStructure } from "@antelopejs/interface-dms-builder";
292
296
 
293
- await ConfigureBlock(
294
- "/revenue#total",
295
- { title: "Revenue" },
296
- { replace: true, expectedVersion: version },
297
- );
297
+ export async function resizeRevenueCard() {
298
+ const read = await GetPageStructure("/revenue");
299
+ if (!read.ok) return read;
300
+
301
+ return ConfigureBlock(
302
+ "/revenue#grid/total",
303
+ { title: "Revenue" },
304
+ { expectedVersion: read.data.version, meta: { colSpan: 2 } },
305
+ );
306
+ }
298
307
  ```
299
308
 
300
309
  An opaque block fails with `opaque_target`: the builder can read it but not rewrite it.
package/docs/6.queries.md CHANGED
@@ -73,7 +73,7 @@ const result = await AddQuery("/books", {
73
73
  });
74
74
  if (result.ok) {
75
75
  console.log(result.data.query); // "/books@inStockCount"
76
- console.log(result.data.route); // "/books/stats/in-stock-count"
76
+ console.log(result.data.route); // "/dms/pages/books/stats/in-stock-count"
77
77
  }
78
78
  ```
79
79
 
@@ -85,11 +85,11 @@ if (result.ok) {
85
85
  | `resource` | `ResourceRef` | The resource the query reads. Required, and it must exist. |
86
86
  | `template` | `string` | A `QueryTemplateDescriptor.id`. Required. |
87
87
  | `params` | `Record<string, QueryParamValue>` | The template's parameters. |
88
- | `endpoint` | `string` | The route path relative to the page's slug. Defaults to `/stats/<kebab-name>`. |
88
+ | `endpoint` | `string` | The route path relative to the page, served at `/dms/pages<pageRef><endpoint>`. Defaults to `/stats/<kebab-name>`. |
89
89
  | `response` | `QueryResponseShape` | How the answer is arranged for the block reading it. Defaults to what the calculation computes. |
90
90
  | `compare` | `boolean` | Also answer the preceding period, so a card can show a variation. |
91
91
 
92
- The result carries both addresses: `query` is the `QueryRef` to configure or remove it by, `route` is the page slug joined with the endpoint — the URL a block fetches from.
92
+ The result carries both addresses: `query` is the `QueryRef` to configure or remove it by, `route` is the URL a block fetches from: the endpoint under the page, at `/dms/pages<pageRef><endpoint>` (`pageRoutePath(pageRef, endpoint)` from `@antelopejs/interface-dms/page`). The DMS serves the routes of a page controller under its own `/dms/pages` prefix, since the page's own path is the page.
93
93
 
94
94
  A few rules the operation enforces:
95
95
 
@@ -143,7 +143,7 @@ await AddQuery("/books", {
143
143
  ],
144
144
  },
145
145
  });
146
- // GET /books/stats/cheaper-than?maxPrice=20
146
+ // GET /dms/pages/books/stats/cheaper-than?maxPrice=20
147
147
  ```
148
148
 
149
149
  | Field | Type | Description |
@@ -164,7 +164,7 @@ Diagnostics are collected across the project, not just the file the operation ed
164
164
 
165
165
  ## Make a Write Conditional
166
166
 
167
- `MutationOpts` is the trailing options argument a mutating operation takes.
167
+ `MutationOpts` is the trailing options argument of version-checked mutations, not of every mutation.
168
168
 
169
169
  | Option | Type | Description |
170
170
  | --- | --- | --- |
@@ -198,4 +198,4 @@ if (!write.ok && write.error.code === "stale") {
198
198
 
199
199
  Omitting `expectedVersion` writes unconditionally. Pass it whenever a human or another process may have touched the file between your read and your write.
200
200
 
201
- Two operations extend `MutationOpts` with a field of their own: `ConfigureBlockOpts` adds `replace`, described in [Page Operations](./4.page-operations.md), and `DeleteResourceOpts` adds `keepData`, described in [Resources](./5.resources.md).
201
+ Two operations extend `MutationOpts` with options of their own: `ConfigureBlockOpts` adds `replace` and `meta`, described in [Page Operations](./4.page-operations.md), and `DeleteResourceOpts` adds `keepData`, described in [Resources](./5.resources.md).
@@ -40,7 +40,7 @@ await SetPageBlocks("/shop/board", {
40
40
  {
41
41
  name: "revenueChart",
42
42
  type: "ChartCard",
43
- config: { title: "Revenue", fetchUrl: "/shop/board/stats/revenue" },
43
+ config: { title: "Revenue", fetchUrl: "/dms/pages/shop/board/stats/revenue" },
44
44
  },
45
45
  ],
46
46
  queries: [
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../tsconfig.json",
3
+ "compilerOptions": {
4
+ "rootDir": "..",
5
+ "composite": false,
6
+ "incremental": false,
7
+ "noEmit": true
8
+ },
9
+ "include": ["../src/**/*.ts", "**/*.ts"]
10
+ }
package/package.json CHANGED
@@ -1,10 +1,23 @@
1
1
  {
2
2
  "name": "@antelopejs/interface-dms-builder",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
+ "description": "AntelopeJS interface for the DMS builder: create and edit pages, blocks, resources and queries in a DMS project from another module.",
5
+ "keywords": [
6
+ "antelopejs",
7
+ "builder",
8
+ "codegen",
9
+ "dms",
10
+ "interface"
11
+ ],
12
+ "homepage": "https://dms.antelopejs.com/docs/modules/builder/extending",
13
+ "bugs": {
14
+ "url": "https://github.com/AntelopeJS/dms-builder/issues"
15
+ },
4
16
  "license": "Apache-2.0",
5
17
  "repository": {
6
18
  "type": "git",
7
- "url": "git+https://github.com/AntelopeJS/dms-builder.git"
19
+ "url": "git+https://github.com/AntelopeJS/dms-builder.git",
20
+ "directory": "packages/interface-dms-builder"
8
21
  },
9
22
  "files": [
10
23
  "LICENSE",
@@ -37,14 +50,14 @@
37
50
  "prepack": "pnpm run build"
38
51
  },
39
52
  "devDependencies": {
40
- "@antelopejs/interface-core": ">=0.2.0 <1.0.0",
53
+ "@antelopejs/interface-core": ">=0.2.4 <1.0.0",
41
54
  "release-it": "^19.2.4",
42
55
  "release-it-changelogen": "^0.1.0",
43
56
  "rimraf": "^6.1.3",
44
57
  "typescript": "^6.0.3"
45
58
  },
46
59
  "peerDependencies": {
47
- "@antelopejs/interface-core": ">=0.1.1 <1.0.0"
60
+ "@antelopejs/interface-core": ">=0.2.4 <1.0.0"
48
61
  },
49
62
  "packageManager": "pnpm@10.2.0",
50
63
  "antelopeJs": {}