@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.
Files changed (52) hide show
  1. package/README.md +4 -4
  2. package/dist/addressing.d.ts +6 -0
  3. package/dist/analysis.d.ts +73 -0
  4. package/dist/analysis.js +18 -1
  5. package/dist/analysis.js.map +1 -1
  6. package/dist/catalog.d.ts +139 -1
  7. package/dist/compose.d.ts +44 -0
  8. package/dist/compose.js +7 -0
  9. package/dist/compose.js.map +1 -1
  10. package/dist/database.d.ts +230 -0
  11. package/dist/database.js +80 -0
  12. package/dist/database.js.map +1 -0
  13. package/dist/drafts.d.ts +61 -0
  14. package/dist/drafts.js +21 -0
  15. package/dist/drafts.js.map +1 -1
  16. package/dist/index.d.ts +2 -0
  17. package/dist/index.js +2 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/mapping.d.ts +122 -0
  20. package/dist/mapping.js +15 -0
  21. package/dist/mapping.js.map +1 -1
  22. package/dist/operation-map.d.ts +27 -1
  23. package/dist/operation-map.js +22 -0
  24. package/dist/operation-map.js.map +1 -1
  25. package/dist/operations.d.ts +57 -0
  26. package/dist/operations.js +18 -0
  27. package/dist/operations.js.map +1 -1
  28. package/dist/project.d.ts +63 -1
  29. package/dist/project.js +10 -0
  30. package/dist/project.js.map +1 -1
  31. package/dist/queries.d.ts +125 -0
  32. package/dist/resources.d.ts +132 -0
  33. package/dist/resources.js +9 -0
  34. package/dist/resources.js.map +1 -1
  35. package/dist/results.d.ts +49 -1
  36. package/dist/structure.d.ts +42 -0
  37. package/dist/table-view.d.ts +49 -0
  38. package/dist/table-view.js +7 -0
  39. package/dist/table-view.js.map +1 -1
  40. package/dist/theme.d.ts +144 -0
  41. package/dist/theme.js +46 -0
  42. package/dist/theme.js.map +1 -0
  43. package/dist/values.d.ts +64 -0
  44. package/dist/values.js +7 -0
  45. package/dist/values.js.map +1 -1
  46. package/docs/1.introduction.md +3 -0
  47. package/docs/10.a-chart-without-code.md +7 -7
  48. package/docs/11.external-databases.md +16 -11
  49. package/docs/11.theme-and-branding.md +135 -0
  50. package/docs/12.connect-a-database.md +87 -0
  51. package/docs/4.page-operations.md +1 -1
  52. package/package.json +15 -8
package/README.md CHANGED
@@ -19,7 +19,7 @@ The AntelopeJS interface that edits the pages, blocks, resources and queries of
19
19
  - Reports every block type and DataType the builder can write, with a schema for its options (`GetCatalog`).
20
20
  - Returns every mutation as an `OpResult`. It holds the files changed on success, and a typed error otherwise.
21
21
 
22
- Every operation is an `InterfaceFunction` routed to [`@antelopejs/dms-builder`](https://www.npmjs.com/package/@antelopejs/dms-builder). That module parses the project, applies the edit as an AST rewrite, and writes only if the project still typechecks.
22
+ Every operation is an `InterfaceFunction` that [`@antelopejs/dms`](https://www.npmjs.com/package/@antelopejs/dms) implements in development. The DMS parses the project, applies the edit as an AST rewrite, and writes only if the project still typechecks.
23
23
 
24
24
  ## Install
25
25
 
@@ -65,11 +65,11 @@ The interface declares this peer dependency:
65
65
 
66
66
  | Package | Supported | Tested with |
67
67
  | ---------------------------- | ---------------- | ----------- |
68
- | `@antelopejs/interface-core` | `>=0.2.4 <1.0.0` | `0.4.0` |
68
+ | `@antelopejs/interface-core` | `>=0.5.1 <1.0.0` | `0.5.1` |
69
69
 
70
70
  <!-- antelopejs-docs-compat:end -->
71
71
 
72
- The `@antelopejs/dms-builder` module implements this interface. The `@antelopejs/interface-dms-builder` row in the compatibility block of the [module README](../dms-builder/README.md#compatibility) gives the interface range each module release implements. The implementation is not a peer dependency of the interface package. It runs in development only, unless its [`api.enabled`](https://dms.antelopejs.com/docs/modules/builder/configuration) option turns it on.
72
+ The `@antelopejs/dms` module implements this interface, and so does the `@antelopejs/dms-builder` module. The `@antelopejs/interface-dms-builder` entry in the `dependencies` of `@antelopejs/dms` gives the interface range each `@antelopejs/dms` release implements. The implementation is not a peer dependency of the interface package. It runs in development only, unless the [`builder.enabled`](https://dms.antelopejs.com/docs/building/configuration) option of `@antelopejs/dms` turns it on.
73
73
 
74
74
  ## Documentation
75
75
 
@@ -79,7 +79,7 @@ The `@antelopejs/dms-builder` module implements this interface. The `@antelopejs
79
79
 
80
80
  ## Contributing
81
81
 
82
- 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.
82
+ This package lives in the [`AntelopeJS/dms`](https://github.com/AntelopeJS/dms) pnpm workspace, next to the module that implements it. Read [CONTRIBUTING.md](https://github.com/AntelopeJS/dms/blob/main/CONTRIBUTING.md) and the [repository README](https://github.com/AntelopeJS/dms#contributing) for the development commands. Release this package before the module that implements it.
83
83
 
84
84
  ## License
85
85
 
@@ -1,3 +1,9 @@
1
+ /** A page's unique route string, e.g. `/settings/profile`. */
1
2
  export type PageRef = string;
3
+ /**
4
+ * A block's address within a page: `<pageRef>#<name>[/<childId>...]`,
5
+ * e.g. `/dashboard#kpis/row/revenue`.
6
+ */
2
7
  export type BlockPath = string;
8
+ /** A category's stable id/slug. */
3
9
  export type CategoryRef = string;
@@ -1,26 +1,34 @@
1
1
  import type { ColumnDisplay, TabsChoice } from "./mapping";
2
2
  import type { ResourceRef } from "./resources";
3
3
  import type { OpResult } from "./results";
4
+ /** Whether a proposed choice follows from the catalog alone, or is a judgement to check. */
4
5
  export type ProposedKind = "fact" | "default";
6
+ /** A choice the analysis made, with the rule that made it. */
5
7
  export interface Proposed<T> {
6
8
  value: T;
9
+ /** The rule's id, e.g. `R6`, `L1`, `F5`. */
7
10
  rule: string;
8
11
  kind: ProposedKind;
9
12
  }
13
+ /** A declaration the analysis chose, and why it does not round-trip when it does not. */
10
14
  export interface ProposedDeclaration extends Proposed<string> {
11
15
  lossy?: string;
12
16
  }
17
+ /** A relation column the analysis chose; `implied` when the database declares no foreign key. */
13
18
  export interface ProposedRelationColumn extends Proposed<string> {
14
19
  implied: boolean;
15
20
  }
21
+ /** The ends of a number, date or enum column. */
16
22
  export interface ProposedRange {
17
23
  min: number | string;
18
24
  max: number | string;
19
25
  }
26
+ /** A category of a column with few distinct values, with its rows. */
20
27
  export interface ProposedCategory {
21
28
  value: string | number | boolean;
22
29
  rows: number;
23
30
  }
31
+ /** What the column's profile measured, for the person deciding: aggregates, never a row. */
24
32
  export interface ProposedColumnProfile {
25
33
  traits: string[];
26
34
  nulls?: number;
@@ -28,9 +36,12 @@ export interface ProposedColumnProfile {
28
36
  range?: ProposedRange;
29
37
  categories?: ProposedCategory[];
30
38
  }
39
+ /** One column of a proposed relation, each aspect with its rule. */
31
40
  export interface ProposedField {
32
41
  column: string;
42
+ /** The column's native type. */
33
43
  native: string;
44
+ /** Every declaration the column accepts, the proposed one among them. */
34
45
  accepts: string[];
35
46
  declared: ProposedDeclaration;
36
47
  label: Proposed<string>;
@@ -38,59 +49,93 @@ export interface ProposedField {
38
49
  filterable: Proposed<boolean>;
39
50
  sortable: Proposed<boolean>;
40
51
  searchable: Proposed<boolean>;
52
+ /** How the column is drawn (D1, D2); absent when it is plain. */
41
53
  display?: Proposed<ColumnDisplay>;
54
+ /** `"schema.name"` of the relation this column refers to, when it becomes a relation column. */
42
55
  relation?: ProposedRelationColumn;
43
56
  profile?: ProposedColumnProfile;
44
57
  }
58
+ /** A column the analysis leaves out, and why. */
45
59
  export interface ProposedLeftOut {
46
60
  column: string;
47
61
  reason: string;
48
62
  rule: string;
49
63
  }
64
+ /** What the analysis's connection may write to a relation. */
50
65
  export interface ProposedWrites {
51
66
  insert: boolean;
52
67
  update: boolean;
53
68
  delete: boolean;
54
69
  }
70
+ /** One relation the analysis proposes to map, in the shape `MapResources` takes. */
55
71
  export interface ProposedResource {
72
+ /** `"schema.name"`. */
56
73
  relation: string;
57
74
  tableView: Proposed<boolean>;
58
75
  writable: Proposed<boolean>;
76
+ /** The column relation columns pointing here show; null when no column is one. */
59
77
  label: Proposed<string | null>;
60
78
  title: Proposed<string>;
79
+ /** The tabs of its TableView (T1); absent when no column suits them. */
61
80
  tabs?: Proposed<TabsChoice>;
62
81
  fields: ProposedField[];
63
82
  leftOut: ProposedLeftOut[];
64
83
  writes: ProposedWrites;
84
+ /** Its rows, counted by the profile or estimated; absent when neither is known. */
65
85
  rows?: number;
86
+ /**
87
+ * The rows its column profiles were measured on: the sample's, when the profile sampled the
88
+ * relation, else its rows. A column's `nulls` is out of these.
89
+ */
66
90
  profiledRows?: number;
67
91
  }
92
+ /** A relation the analysis does not propose, and why. */
68
93
  export interface ProposedExclusion {
69
94
  relation: string;
70
95
  reason: string;
71
96
  rule: string;
72
97
  }
98
+ /**
99
+ * The kinds of question the rules leave open. A `field-type` item asks which declaration reads a
100
+ * column whose values have several native types, none covering enough of them: unanswered, the
101
+ * column is left out.
102
+ */
73
103
  export type OpenItemKind = "schemas" | "purpose" | "label" | "reference" | "field-type";
104
+ /** One answer an open item offers. */
74
105
  export interface OpenItemOption {
75
106
  value: unknown;
76
107
  title: string;
77
108
  }
109
+ /** A question the rules could not decide, with its options. */
78
110
  export interface OpenItem {
111
+ /** Stable across runs, e.g. `label:erp.customers`. */
79
112
  id: string;
80
113
  kind: OpenItemKind;
81
114
  relation?: string;
82
115
  column?: string;
83
116
  question: string;
84
117
  options: OpenItemOption[];
118
+ /** What the proposal holds meanwhile, if anything. */
85
119
  proposed: unknown;
120
+ /** For a `purpose` item, the relation as it would be mapped should the answer be to map it. */
86
121
  resource?: ProposedResource;
122
+ /**
123
+ * For a `purpose` item, the questions its `resource` leaves open, to answer should the answer be
124
+ * to map it. Absent when it leaves none.
125
+ */
87
126
  open?: OpenItem[];
88
127
  }
128
+ /** The connected database, as the analysis's connection sees it. */
89
129
  export interface ProposalDatabase {
90
130
  engine: string;
91
131
  role: string;
92
132
  writes: "none" | "some" | "all";
93
133
  }
134
+ /**
135
+ * A mapping of a connection's relations into a module, proposed from the catalog by fixed rules.
136
+ * Every choice names its rule. It writes nothing: settling it and sending it to `MapResources` is
137
+ * the caller's.
138
+ */
94
139
  export interface MappingProposal {
95
140
  connection: string;
96
141
  module: string;
@@ -99,19 +144,25 @@ export interface MappingProposal {
99
144
  excluded: ProposedExclusion[];
100
145
  open: OpenItem[];
101
146
  }
147
+ /** Which connection to analyse, for which module, optionally limited to some schemas. */
102
148
  export interface AnalyseDatabaseInput {
149
+ /** The id of the builder's catalog connection. */
103
150
  connection: string;
151
+ /** The module the mapping is for; relations mapped or excluded there are not proposed again. */
104
152
  module: string;
105
153
  schemas?: string[];
106
154
  }
155
+ /** How far an analysis has come. */
107
156
  export interface AnalysisProgress {
108
157
  relations: number;
109
158
  described: number;
110
159
  toProfile: number;
111
160
  profiled: number;
161
+ /** Measures that did not finish in their time. */
112
162
  timeouts: number;
113
163
  }
114
164
  export type AnalysisStatus = "running" | "done" | "failed";
165
+ /** An analysis job: its progress, then its proposal or its failure. */
115
166
  export interface AnalysisState {
116
167
  id: string;
117
168
  connection: string;
@@ -120,11 +171,33 @@ export interface AnalysisState {
120
171
  proposal?: MappingProposal;
121
172
  error?: string;
122
173
  }
174
+ /**
175
+ * Starts an analysis of a connection's database, and answers its job at once. Profiling is
176
+ * slow, so the proposal comes later through `GetAnalysis`. One job runs per connection; starting
177
+ * another while one runs answers the running one.
178
+ */
123
179
  export declare const AnalyseDatabase: (input: AnalyseDatabaseInput) => Promise<OpResult<AnalysisState>>;
180
+ /**
181
+ * An analysis job's progress, then its proposal. A finished job is kept until the next one on
182
+ * its connection, or a restart.
183
+ */
124
184
  export declare const GetAnalysis: (id: string) => Promise<OpResult<AnalysisState>>;
185
+ /**
186
+ * The latest analysis of a connection: the running one, or else the last to finish. `not_found`
187
+ * when none ran since the start.
188
+ *
189
+ * Owner path only: no MCP tool exposes it, so only an owner-authenticated entry calls it.
190
+ */
191
+ export declare const GetLatestAnalysis: (connection: string) => Promise<OpResult<AnalysisState>>;
192
+ /**
193
+ * A relation a module maps, read back from its code as its current choices, in a proposal's shape:
194
+ * every choice cites the rule `mapped`.
195
+ */
125
196
  export interface MappedRelation {
126
197
  ref: ResourceRef;
127
198
  resource: ProposedResource;
199
+ /** The columns the module declares; the rest of `resource.fields` are the catalog's others. */
128
200
  included: string[];
129
201
  }
202
+ /** The relations a module maps for a connection, as their current choices, to change and map again. */
130
203
  export declare const GetMapping: (connection: string, module: string) => Promise<OpResult<MappedRelation[]>>;
package/dist/analysis.js CHANGED
@@ -1,8 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GetMapping = exports.GetAnalysis = exports.AnalyseDatabase = void 0;
3
+ exports.GetMapping = exports.GetLatestAnalysis = exports.GetAnalysis = exports.AnalyseDatabase = void 0;
4
4
  const interface_core_1 = require("@antelopejs/interface-core");
5
+ /**
6
+ * Starts an analysis of a connection's database, and answers its job at once. Profiling is
7
+ * slow, so the proposal comes later through `GetAnalysis`. One job runs per connection; starting
8
+ * another while one runs answers the running one.
9
+ */
5
10
  exports.AnalyseDatabase = (0, interface_core_1.InterfaceFunction)();
11
+ /**
12
+ * An analysis job's progress, then its proposal. A finished job is kept until the next one on
13
+ * its connection, or a restart.
14
+ */
6
15
  exports.GetAnalysis = (0, interface_core_1.InterfaceFunction)();
16
+ /**
17
+ * The latest analysis of a connection: the running one, or else the last to finish. `not_found`
18
+ * when none ran since the start.
19
+ *
20
+ * Owner path only: no MCP tool exposes it, so only an owner-authenticated entry calls it.
21
+ */
22
+ exports.GetLatestAnalysis = (0, interface_core_1.InterfaceFunction)();
23
+ /** The relations a module maps for a connection, as their current choices, to change and map again. */
7
24
  exports.GetMapping = (0, interface_core_1.InterfaceFunction)();
8
25
  //# sourceMappingURL=analysis.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"analysis.js","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":";;;AAAA,+DAA+D;AA8MlD,QAAA,eAAe,GAC1B,IAAA,kCAAiB,GAEd,CAAC;AAMO,QAAA,WAAW,GACtB,IAAA,kCAAiB,GAAoD,CAAC;AAc3D,QAAA,UAAU,GACrB,IAAA,kCAAiB,GAEd,CAAC"}
1
+ {"version":3,"file":"analysis.js","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":";;;AAAA,+DAA+D;AAyM/D;;;;GAIG;AACU,QAAA,eAAe,GAC1B,IAAA,kCAAiB,GAEd,CAAC;AAEN;;;GAGG;AACU,QAAA,WAAW,GACtB,IAAA,kCAAiB,GAAoD,CAAC;AAExE;;;;;GAKG;AACU,QAAA,iBAAiB,GAC5B,IAAA,kCAAiB,GAA4D,CAAC;AAahF,uGAAuG;AAC1F,QAAA,UAAU,GACrB,IAAA,kCAAiB,GAEd,CAAC"}
package/dist/catalog.d.ts CHANGED
@@ -1,44 +1,103 @@
1
1
  import type { ConfigObject } from "./values";
2
+ /**
3
+ * An import the emitter must add: `import { <name> } from "<module>"`. Either a
4
+ * package `module` specifier (fixed, file-independent) or a `targetFile` absolute
5
+ * path resolved to a relative specifier against the emitting file (e.g. a `$ref`
6
+ * to a local resource class).
7
+ */
2
8
  export interface ImportRef {
3
9
  name: string;
4
10
  module?: string;
5
11
  targetFile?: string;
6
12
  }
13
+ /** A named region of a container block (e.g. a Tab's slots). */
7
14
  export interface SlotDescriptor {
8
15
  id: string;
9
16
  label?: string;
10
17
  description?: string;
11
18
  }
19
+ /**
20
+ * A container whose slots come from its own options rather than being fixed —
21
+ * `Tab`, whose `items[].slot` names each region. Read the option at `optionPath`
22
+ * of the block's config to enumerate them.
23
+ */
12
24
  export interface DynamicSlots {
13
25
  optionPath: string;
14
26
  idKey: string;
15
27
  labelKey?: string;
16
28
  }
29
+ /** The editor control an option is best edited with. */
17
30
  export type OptionWidget = "text" | "textarea" | "number" | "range" | "switch" | "select" | "segmented" | "icon" | "color" | "url" | "resource" | "field" | "dataType" | "dataSource" | "permission" | "json" | "block";
31
+ /** How a builder UI should present one option. */
32
+ /** A resource aspect a field must carry for an option naming it to work. */
18
33
  export type FieldAspect = "listable" | "searchable" | "sortable" | "filterable";
19
34
  export interface OptionUi {
20
35
  label?: string;
21
36
  widget?: OptionWidget;
37
+ /** Section the option belongs to: `content` | `data` | `appearance` | … */
22
38
  group?: string;
23
39
  order?: number;
40
+ /** Not editable from a config panel — transport-only or code-only. */
24
41
  hidden?: boolean;
25
42
  placeholder?: string;
26
43
  min?: number;
27
44
  max?: number;
28
45
  step?: number;
46
+ /** Dotted path to the option whose value scopes this one. */
29
47
  scope?: string;
48
+ /** Block types a `block` widget accepts. */
30
49
  blockTypes?: string[];
50
+ /**
51
+ * The options of the block a `block` widget holds that the block holding it
52
+ * supplies itself: a card fetches and heads the chart it wraps.
53
+ */
31
54
  supplies?: string[];
55
+ /**
56
+ * The aspect, or aspects, a `field` widget's value must carry on the
57
+ * resource. Naming a field that lacks one is written and then ignored at
58
+ * runtime, so it is refused instead.
59
+ */
32
60
  fieldAspect?: FieldAspect | FieldAspect[];
61
+ /**
62
+ * Render an object option's own properties in its group rather than nested
63
+ * under its label — a set of switches that reads as one list of features.
64
+ */
33
65
  flatten?: boolean;
66
+ /**
67
+ * What to call each value of an enum, keyed by the value: `Last 30 days`
68
+ * rather than `last-30-days`.
69
+ */
34
70
  valueLabels?: Record<string, string>;
71
+ /**
72
+ * The sibling option this one's value can be derived from — a field's key
73
+ * from its label. The builder writes it itself in its simple mode.
74
+ */
35
75
  derivedFrom?: string;
76
+ /**
77
+ * The switch this option sits behind, by its label: offered once an author
78
+ * turns it on, left out while it is off.
79
+ */
36
80
  optIn?: string;
81
+ /**
82
+ * The sibling option holding the data type this value is one of: a field's
83
+ * default takes the input its type calls for.
84
+ */
37
85
  typedBy?: string;
86
+ /** Offered in the builder's advanced view only. */
38
87
  advanced?: boolean;
88
+ /** What the builder places a new block with, when not the option's default. */
39
89
  initial?: unknown;
40
90
  }
41
- export type OptionType = "string" | "number" | "boolean" | "object" | "array" | "record" | "union" | "unknown";
91
+ /** The primitive kinds a described option reduces to. */
92
+ export type OptionType = "string" | "number" | "boolean" | "object" | "array" | "record"
93
+ /** Branches of differing kinds; read `oneOf` rather than `type`. */
94
+ | "union" | "unknown";
95
+ /**
96
+ * A JSON-Schema-ish description of one option. Two DMS extensions carry over
97
+ * from the inferred path: `x-dataType` marks a value that is a
98
+ * `new <DataType>(...)` instance (a Form field's `type`), and `x-component`
99
+ * marks one that holds a nested component.
100
+ */
42
101
  export interface OptionSchema {
43
102
  type: OptionType;
44
103
  optional?: boolean;
@@ -46,68 +105,147 @@ export interface OptionSchema {
46
105
  description?: string;
47
106
  default?: unknown;
48
107
  enum?: Array<string | number | boolean>;
108
+ /** Object shape, keyed by property name. */
49
109
  properties?: Record<string, OptionSchema>;
110
+ /** Array element shape. */
50
111
  items?: OptionSchema;
112
+ /** Record value shape. */
51
113
  values?: OptionSchema;
114
+ /**
115
+ * Record key shape. A key drawn from a closed set carries it as `enum`, so
116
+ * an editor can offer one entry per key.
117
+ */
52
118
  keys?: OptionSchema;
119
+ /** Union branches, in declaration order. */
53
120
  oneOf?: OptionSchema[];
121
+ /** Property carrying the branch tag of a discriminated union. */
54
122
  discriminator?: string;
123
+ /** Positional element shapes of a tuple, in order. */
55
124
  prefixItems?: OptionSchema[];
125
+ /** Shapes a value must satisfy at once, for an intersection. */
56
126
  allOf?: OptionSchema[];
127
+ /**
128
+ * The shape is deeper than the catalog describes. What is reported is
129
+ * accurate as far as it goes; the value has more structure below it.
130
+ */
57
131
  truncated?: boolean;
58
132
  ui?: OptionUi;
59
133
  "x-dataType"?: boolean;
60
134
  "x-component"?: boolean;
135
+ /**
136
+ * The option is handed a table's DataAPI class — a relation's
137
+ * `dataApiController`. Its value is a `$ref` to a resource.
138
+ */
61
139
  "x-controller"?: boolean;
62
140
  }
141
+ /**
142
+ * A block's or DataType's options, keyed by option name. Declared schemas
143
+ * (`configOrigin: "annotated"`) carry labels, defaults and widgets; inferred ones
144
+ * carry only what the TypeScript signature revealed.
145
+ */
63
146
  export type ConfigSchema = Record<string, OptionSchema>;
147
+ /** How a block type's emit shape was determined. */
64
148
  export type ConfigOrigin = "inferred" | "annotated";
149
+ /**
150
+ * The palette section a block type belongs to. The four the DMS ships are
151
+ * spelled out; a newer DMS declaring another one passes through rather than
152
+ * being dropped, so its blocks stay listable.
153
+ */
65
154
  export type BlockGroup = "layout" | "content" | "data" | "visualization" | (string & {});
155
+ /** A block factory the builder can emit and configure. Keyed on `type`. */
66
156
  export interface BlockTypeDescriptor {
157
+ /** Factory export name, e.g. `KpiCard` — the catalog key. */
67
158
  type: string;
68
159
  import: ImportRef;
160
+ /** Frontend component name the factory emits, e.g. `dms-kpi-card`. */
69
161
  componentName?: string;
162
+ /** Human label for the palette; falls back to `type`. */
70
163
  label?: string;
71
164
  icon?: string;
72
165
  group?: BlockGroup;
166
+ /** Whether the block accepts `.child(...)`. */
73
167
  container: boolean;
168
+ /** Block types accepted as children; any type when absent. */
74
169
  allowedChildren?: string[];
75
170
  slots?: SlotDescriptor[];
76
171
  dynamicSlots?: DynamicSlots;
77
172
  config: ConfigSchema;
173
+ /** Option values the factory applies when the caller omits them. */
78
174
  defaults?: ConfigObject;
175
+ /** Schema of the metadata a child carries, e.g. `{ colSpan }`. */
79
176
  childMeta?: ConfigSchema;
177
+ /**
178
+ * Options the factory sets itself whatever the caller passes — a chart's
179
+ * `type`, which is what tells `dms-chart-block` which chart to draw. Emitting them
180
+ * is unnecessary; a consumer rendering from the descriptor alone merges them
181
+ * in.
182
+ */
80
183
  fixedOptions?: ConfigObject;
81
184
  configOrigin: ConfigOrigin;
82
185
  description?: string;
186
+ /**
187
+ * True when the factory takes a leading controller-class argument before its
188
+ * options object (e.g. `TableView(controller, options)`). Such blocks require
189
+ * `AddBlockInput.controller`; `config` describes the options (second) argument.
190
+ */
83
191
  controllerArg?: boolean;
192
+ /**
193
+ * The children an editor places in a new block of this type, as the DMS's
194
+ * own helper places them in code: a `PageToolbar`'s `LiveToggle` and
195
+ * `PeriodSelector` with the defaults of `pageToolbar()`.
196
+ */
84
197
  initialChildren?: BlockInitialChild[];
85
198
  }
199
+ /** One child a new block starts with (see `BlockTypeDescriptor.initialChildren`). */
86
200
  export interface BlockInitialChild {
201
+ /** The child id under its parent, the one roles name it by. */
87
202
  id: string;
203
+ /** The child's block type, a key of the catalog (`LiveToggle`). */
88
204
  type: string;
205
+ /** The child's options. */
89
206
  options: ConfigObject;
90
207
  }
208
+ /** A DataType usable as a Form field's `type`. */
91
209
  export interface DataTypeDescriptor {
210
+ /** Registered id, e.g. `string` | `number` | `select`. */
92
211
  id: string;
93
212
  import: ImportRef;
94
213
  config: ConfigSchema;
95
214
  description?: string;
96
215
  }
216
+ /** The full set of block types and DataTypes the builder can emit. */
97
217
  export interface BlockCatalog {
98
218
  blocks: BlockTypeDescriptor[];
99
219
  dataTypes: DataTypeDescriptor[];
220
+ /**
221
+ * Names a resource field may not take: they collide with a generated
222
+ * DataController route or a Model member, and are rejected with
223
+ * `invalid_config`. Reported here so a caller can pick a valid name up front
224
+ * rather than carrying its own copy of the list.
225
+ */
100
226
  reservedFieldNames: string[];
227
+ /** Cache key; invalidated on module-source change. */
101
228
  generatedAt: string;
102
229
  }
230
+ /**
231
+ * A route a developer declared as something a block may read.
232
+ *
233
+ * Listed beside the calculations the builder generates, so a source editor
234
+ * offers both in one place. The builder never reads or rewrites the code behind
235
+ * one: it knows only what the declaration says.
236
+ */
103
237
  export interface DataSourceDescriptor {
104
238
  id: string;
105
239
  title: string;
106
240
  description?: string;
241
+ /** The shape it answers with, matched against what a block can read. */
107
242
  responseKind: string;
243
+ /** The path a block fetches, as declared. */
108
244
  path: string;
109
245
  method?: string;
246
+ /** Parameters it takes, in the same vocabulary as a block's options. */
110
247
  params?: ConfigSchema;
248
+ /** The query parameters it reads a period from, when it takes one. */
111
249
  period?: {
112
250
  from: string;
113
251
  to: string;
package/dist/compose.d.ts CHANGED
@@ -4,52 +4,96 @@ import type { AddQueryInput, QueryPreview, QueryRef } from "./queries";
4
4
  import type { AddBlockInput, CreatePageInput } from "./operations";
5
5
  import type { ResourceRef } from "./resources";
6
6
  import type { MutationOpts, OpResult } from "./results";
7
+ /**
8
+ * The query a data block reads, in {@link AddQueryInput}'s shape. The route it
9
+ * compiles to is written into the block's config, under `into`.
10
+ */
7
11
  export interface ComposeQuery extends Omit<AddQueryInput, "name"> {
12
+ /** The query's name; defaults to the block's name. */
8
13
  name?: string;
14
+ /** The block config key that receives the route. Defaults to `fetchUrl`. */
9
15
  into?: string;
16
+ /** Values for this query's preview, overriding {@link ComposePageInput.args}. */
10
17
  args?: QueryPreviewRequest["args"];
11
18
  }
19
+ /** One block of a composed page; a container carries its blocks in `children`. */
12
20
  export interface ComposeBlock {
21
+ /** Unique among its siblings. */
13
22
  name: string;
23
+ /** A block type from the catalog, e.g. `GridRow`, `KpiCard`, `ChartCard`. */
14
24
  type: string;
15
25
  config?: AddBlockInput["config"];
26
+ /** The resource whose DataAPI leads a controller-leading block such as `TableView`. */
16
27
  controller?: ResourceRef;
28
+ /** The slot this block fills in its container. */
17
29
  slot?: string;
30
+ /** Child metadata such as `{ colSpan: 2 }` in a grid. */
18
31
  meta?: AddBlockInput["meta"];
32
+ /** The query this block reads; added to the page with the block. */
19
33
  query?: ComposeQuery;
34
+ /** Blocks nested in this one, in order. */
20
35
  children?: ComposeBlock[];
21
36
  }
37
+ /** Where the new blocks go among the siblings already there: next to the block named. */
22
38
  export interface ComposePlacement {
23
39
  before?: string;
24
40
  after?: string;
25
41
  }
42
+ /**
43
+ * Input for `ComposePage`: builds a whole page, or extends one, in one call.
44
+ * Name the page with `page`, or give the fields of one to create with `create`.
45
+ */
26
46
  export interface ComposePageInput {
27
47
  page?: PageRef;
28
48
  create?: CreatePageInput;
49
+ /** An existing container to add the blocks under; omit for the page itself. */
29
50
  parent?: BlockPath;
51
+ /** Position among the siblings already under `parent`; omit to append. */
30
52
  placement?: ComposePlacement;
53
+ /** The blocks to add, in order. */
31
54
  blocks: ComposeBlock[];
55
+ /**
56
+ * Run every query against the database and answer each block's result without
57
+ * writing anything. A second call without it writes.
58
+ */
32
59
  preview?: boolean;
60
+ /** The values every query's route would receive, e.g. `{ from, to }`; used by `preview`. */
33
61
  args?: QueryPreviewRequest["args"];
62
+ /** The tenant whose rows a preview reads. */
34
63
  tenant?: string;
35
64
  }
65
+ /** A block the call added. */
36
66
  export interface ComposedBlock {
67
+ /** Where the block sits in the input, e.g. `/blocks/1/children/0`. */
37
68
  pointer: string;
38
69
  path: BlockPath;
39
70
  query?: QueryRef;
71
+ /** The route the block reads, as written into its config. */
40
72
  route?: string;
41
73
  }
74
+ /** What one block's query answered in a preview. */
42
75
  export interface ComposePreviewBlock {
43
76
  pointer: string;
44
77
  block: string;
78
+ /** `empty`: no rows. `zero`: rows, but every figure is zero or missing. `error`: the query was refused. */
45
79
  status: "ok" | "empty" | "zero" | "error";
46
80
  preview?: QueryPreview;
81
+ /** Why the query was refused, when `status` is `error`. */
47
82
  error?: string;
48
83
  }
49
84
  export interface ComposePageData {
50
85
  page: PageRef;
86
+ /** False for a preview. */
51
87
  written: boolean;
52
88
  blocks: ComposedBlock[];
89
+ /** One entry per block that reads a query; filled by a preview. */
53
90
  previews: ComposePreviewBlock[];
54
91
  }
92
+ /**
93
+ * Builds a page, or adds to one, in one operation: one rewrite of the page, one of
94
+ * the models, one typecheck, and nothing written when any block is refused. A
95
+ * refusal is `invalid_config` whose issues carry a JSON pointer into the input
96
+ * (`/blocks/2/children/0/query/params/...`) per refused block, or
97
+ * `typecheck_failed` when the whole would not compile.
98
+ */
55
99
  export declare const ComposePage: (input: ComposePageInput, opts?: MutationOpts | undefined) => Promise<OpResult<ComposePageData>>;
package/dist/compose.js CHANGED
@@ -2,5 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ComposePage = void 0;
4
4
  const interface_core_1 = require("@antelopejs/interface-core");
5
+ /**
6
+ * Builds a page, or adds to one, in one operation: one rewrite of the page, one of
7
+ * the models, one typecheck, and nothing written when any block is refused. A
8
+ * refusal is `invalid_config` whose issues carry a JSON pointer into the input
9
+ * (`/blocks/2/children/0/query/params/...`) per refused block, or
10
+ * `typecheck_failed` when the whole would not compile.
11
+ */
5
12
  exports.ComposePage = (0, interface_core_1.InterfaceFunction)();
6
13
  //# sourceMappingURL=compose.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"compose.js","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":";;;AAAA,+DAA+D;AA2GlD,QAAA,WAAW,GACtB,IAAA,kCAAiB,GAKd,CAAC"}
1
+ {"version":3,"file":"compose.js","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":";;;AAAA,+DAA+D;AAoG/D;;;;;;GAMG;AACU,QAAA,WAAW,GACtB,IAAA,kCAAiB,GAKd,CAAC"}