cedar-embeddable-editor 1.5.2 → 2.0.2
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/CHANGELOG.md +1032 -0
- package/README.md +153 -267
- package/bundle-manifest.json +9 -0
- package/cedar-embeddable-editor.d.ts +298 -0
- package/cedar-embeddable-editor.js +6053 -1
- package/license.txt +26 -0
- package/package.json +17 -11
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The contract an embedding page programs against.
|
|
3
|
+
*
|
|
4
|
+
* Everything here is deliberately self-contained: no imports, and no reference to
|
|
5
|
+
* a type declared elsewhere in CEE. That is not tidiness — it is what lets
|
|
6
|
+
* `tsc --emitDeclarationOnly` turn this one file into the `.d.ts` the npm package
|
|
7
|
+
* ships, without dragging in paths that exist only inside this repository.
|
|
8
|
+
*
|
|
9
|
+
* Configuration and the artifact inputs are set-once: the first assignment stands,
|
|
10
|
+
* and a later one is reported and ignored. A host wanting different configuration or
|
|
11
|
+
* a different artifact creates a new element. That replaces three behaviours which
|
|
12
|
+
* had no answer — a second `config` that patched some keys and replaced others, a
|
|
13
|
+
* read-only mode that could be turned on and not off, and three artifact inputs with
|
|
14
|
+
* no stated precedence. `eventHandler` is deliberately outside it and may be
|
|
15
|
+
* replaced, for the reasons given where it is declared.
|
|
16
|
+
*
|
|
17
|
+
* Types only, with no runtime values, and that is a constraint rather than a
|
|
18
|
+
* style. The shipped bundle is an IIFE that registers a custom element and exports
|
|
19
|
+
* nothing at all, so a `const` declared here would satisfy a host's compiler and
|
|
20
|
+
* then be `undefined` at runtime. Publishing key names as constants has to wait for
|
|
21
|
+
* the package to export anything.
|
|
22
|
+
*
|
|
23
|
+
* `cee-public-api.spec.ts` checks this file against the implementation: every key
|
|
24
|
+
* the editor component reads must appear on `CeeConfig` and vice versa, so the
|
|
25
|
+
* contract cannot drift from the code by being edited in only one place.
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* A configuration key, as a type.
|
|
29
|
+
*
|
|
30
|
+
* Every key of `CeeConfig`, now that the interface is closed. It was
|
|
31
|
+
* `Exclude<keyof CeeConfig, number | symbol>`, which is what an index signature
|
|
32
|
+
* costs: `keyof` on an open interface is `string | number | symbol`, so the type
|
|
33
|
+
* of a key had to be narrowed back down by hand and named nothing more precise
|
|
34
|
+
* than "a string".
|
|
35
|
+
*/
|
|
36
|
+
export type CeeConfigKey = keyof CeeConfig;
|
|
37
|
+
/**
|
|
38
|
+
* The configuration CEE accepts.
|
|
39
|
+
*
|
|
40
|
+
* Every key is optional and an omitted key takes its default, because
|
|
41
|
+
* configuration is applied once and never merged with a previous assignment.
|
|
42
|
+
*/
|
|
43
|
+
export interface CeeConfig {
|
|
44
|
+
showTemplateDescription?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Renders the form without editing controls.
|
|
47
|
+
*
|
|
48
|
+
* The only way in or out of read-only mode. CEE offered the user a toggle of its
|
|
49
|
+
* own, which wrote to the same state the widgets read, so a form embedded as a
|
|
50
|
+
* viewer could be made editable from inside it.
|
|
51
|
+
*/
|
|
52
|
+
readOnlyMode?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Whether a template author's rich text renders verbatim.
|
|
55
|
+
*
|
|
56
|
+
* Defaults to false, which sanitizes. Set true only if template authors are as
|
|
57
|
+
* trusted as your own application code — see the README's embedding-security
|
|
58
|
+
* section.
|
|
59
|
+
*/
|
|
60
|
+
trustTemplateRichText?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Offers a menu that saves CEE's views of the artifact as files — the instance
|
|
63
|
+
* as JSON-LD plus standard and compact YAML, the template as JSON Schema plus
|
|
64
|
+
* standard and compact YAML, and the data quality report.
|
|
65
|
+
*
|
|
66
|
+
* Off by default, so an embedded form offers nothing of the sort unless a host
|
|
67
|
+
* asks. Nothing is rendered under the form either way.
|
|
68
|
+
*/
|
|
69
|
+
showDownloadMenu?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Base for controlled-term search. Must end in a slash.
|
|
72
|
+
*
|
|
73
|
+
* Identifies the CEDAR terminology server, and nothing below it: the search
|
|
74
|
+
* path hangs off this and is CEE's own. Unset, controlled fields offer no
|
|
75
|
+
* terms, and CEE says so once.
|
|
76
|
+
*
|
|
77
|
+
* This was `terminologyIntegratedSearchUrl` and took the endpoint whole, so
|
|
78
|
+
* every host spelled out `bioportal/integrated-search` — a route belonging to
|
|
79
|
+
* the terminology server, restated in four deployment configs that would all
|
|
80
|
+
* have to change together if it ever moved.
|
|
81
|
+
*/
|
|
82
|
+
terminologyBaseUrl?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Base for every external authority lookup. Must end in a slash.
|
|
85
|
+
*
|
|
86
|
+
* Identifies the CEDAR bridge server, and nothing below it: the fourteen
|
|
87
|
+
* endpoints behind the seven authority fields hang off this and are CEE's own,
|
|
88
|
+
* so a deployment moves all of them by moving this, or none of them. Fourteen
|
|
89
|
+
* keys used to offer the paths one at a time, and every host that set one
|
|
90
|
+
* restated the default.
|
|
91
|
+
*
|
|
92
|
+
* Unset, authority fields offer no terms and resolve no identifiers, and CEE
|
|
93
|
+
* says so once. There was a default — the production bridge — which a host
|
|
94
|
+
* embedding CEE anywhere else reached without asking and without knowing.
|
|
95
|
+
*
|
|
96
|
+
* This was `extAuthBaseUrl` and took the bridge server's `ext-auth/` resource
|
|
97
|
+
* root, the one path segment a host was still left spelling.
|
|
98
|
+
*/
|
|
99
|
+
bridgeBaseUrl?: string;
|
|
100
|
+
defaultLanguage?: string;
|
|
101
|
+
fallbackLanguage?: string;
|
|
102
|
+
languageMapPathPrefix?: string;
|
|
103
|
+
}
|
|
104
|
+
/** A JSON-serialisable value, as it appears in a CEDAR artifact. */
|
|
105
|
+
export type CeeJsonValue = string | number | boolean | null | CeeJsonObject | CeeJsonValue[];
|
|
106
|
+
export interface CeeJsonObject {
|
|
107
|
+
[key: string]: CeeJsonValue;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* A template and an instance of it, supplied together.
|
|
111
|
+
*
|
|
112
|
+
* The members are `templateObject` and `instanceObject`, the same names the two
|
|
113
|
+
* separate inputs carry. They were published here as `template` and `instance`,
|
|
114
|
+
* which read better and are not what the editor destructures — a host following
|
|
115
|
+
* the declaration got "Template Object is missing." at runtime. Nothing checked
|
|
116
|
+
* the two against each other, so the names could differ without either side
|
|
117
|
+
* looking wrong on its own.
|
|
118
|
+
*/
|
|
119
|
+
export interface CeeTemplateAndInstance {
|
|
120
|
+
templateObject: CeeJsonObject;
|
|
121
|
+
instanceObject: CeeJsonObject;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* One thing wrong with the instance, as the data quality report sees it.
|
|
125
|
+
*
|
|
126
|
+
* Every member the runtime object carries, unlike `CeeDataQualityReport`, which
|
|
127
|
+
* declares a subset because the report also holds CEE's internal working views. A
|
|
128
|
+
* problem has no internals — it exists to be read by a host — so anything missing
|
|
129
|
+
* here is missing by mistake, which `field` and `inputType` were: documented in the
|
|
130
|
+
* validation guide, present at runtime, and absent from this interface, so a
|
|
131
|
+
* TypeScript host could not read either without a cast.
|
|
132
|
+
*/
|
|
133
|
+
export interface CeeValidationProblem {
|
|
134
|
+
/** Machine-readable code, e.g. `numberType` or `temporalGranularity`. */
|
|
135
|
+
code: string;
|
|
136
|
+
/** Path to the offending value, outermost first. */
|
|
137
|
+
path: string[];
|
|
138
|
+
/** The field's property name, which is the last path segment. */
|
|
139
|
+
field: string;
|
|
140
|
+
/** The field's declared `_ui.inputType`, or null where it declares none. */
|
|
141
|
+
inputType: string | null;
|
|
142
|
+
/** Human-readable explanation. */
|
|
143
|
+
message: string;
|
|
144
|
+
/** The value that failed, when there is one. */
|
|
145
|
+
value?: unknown;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* What CEE thinks of the instance currently in the form.
|
|
149
|
+
*
|
|
150
|
+
* Read through `dataQualityReport`. These four members are the whole object: it
|
|
151
|
+
* carried three of CEE's internal working views as well, and the interface was a
|
|
152
|
+
* subset of what a host actually received.
|
|
153
|
+
*/
|
|
154
|
+
export interface CeeDataQualityReport {
|
|
155
|
+
/**
|
|
156
|
+
* How many required fields the template declares.
|
|
157
|
+
*
|
|
158
|
+
* One per declaration, whatever its cardinality — a required field repeated
|
|
159
|
+
* five times counts once, as does a required field inside an element repeated
|
|
160
|
+
* five times.
|
|
161
|
+
*/
|
|
162
|
+
requiredFieldValueCount: number;
|
|
163
|
+
/**
|
|
164
|
+
* How many of those the instance fills.
|
|
165
|
+
*
|
|
166
|
+
* A requirement is met when any occurrence carries a value, so this is
|
|
167
|
+
* unaffected by which page the form is showing.
|
|
168
|
+
*/
|
|
169
|
+
nonNullRequiredFieldValueCount: number;
|
|
170
|
+
/**
|
|
171
|
+
* Validation problems.
|
|
172
|
+
*
|
|
173
|
+
* Includes one `required` problem for each unsatisfied required field
|
|
174
|
+
* declaration, while the two counters retain their existing aggregate view.
|
|
175
|
+
*/
|
|
176
|
+
problems: CeeValidationProblem[];
|
|
177
|
+
/** True when every required field is filled and no constraint is violated. */
|
|
178
|
+
isValid: boolean;
|
|
179
|
+
}
|
|
180
|
+
/** The model operation that produced a host-visible instance change. */
|
|
181
|
+
export type CeeChangeOperation = 'valueChanged' | 'multiInstanceAdded' | 'multiInstanceCopied' | 'multiInstanceDeleted';
|
|
182
|
+
/**
|
|
183
|
+
* Detail carried by CEE's composed `change` event.
|
|
184
|
+
*
|
|
185
|
+
* This describes a change to the serialized instance, not traffic from a DOM
|
|
186
|
+
* control. Paging, focus, blur and a write which leaves the instance identical
|
|
187
|
+
* therefore produce no event.
|
|
188
|
+
*/
|
|
189
|
+
export interface CeeChangeDetail {
|
|
190
|
+
/** What changed. */
|
|
191
|
+
operation: CeeChangeOperation;
|
|
192
|
+
/** Template path of the changed field or multi-instance component. */
|
|
193
|
+
path: string[];
|
|
194
|
+
/** The value supplied to the model operation. */
|
|
195
|
+
value: unknown;
|
|
196
|
+
/** Current validity after the operation. */
|
|
197
|
+
validity: boolean;
|
|
198
|
+
/** Current validation report after the operation. */
|
|
199
|
+
dataQualityReport: CeeDataQualityReport;
|
|
200
|
+
/** Current instance title, where the envelope carries one. */
|
|
201
|
+
title: string | null;
|
|
202
|
+
/** Current instance description, where the envelope carries one. */
|
|
203
|
+
description: string | null;
|
|
204
|
+
/** Backward-compatible name carried by the three multi-instance operations. */
|
|
205
|
+
message?: 'multiInstanceAdded' | 'multiInstanceCopied' | 'multiInstanceDeleted';
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* The callbacks CEE will invoke on the host.
|
|
209
|
+
*
|
|
210
|
+
* Supplied through the `eventHandler` input. Every member is optional, and a
|
|
211
|
+
* handler is called only if it has a matching method — so `{ error }` on its own
|
|
212
|
+
* is a valid handler and will not be bothered with traces.
|
|
213
|
+
*
|
|
214
|
+
* `trace`, `error`, `valueChanged`, and `ready` are emitted by
|
|
215
|
+
* `MessageHandlerService`. `message` remains declared for compatibility but is
|
|
216
|
+
* not emitted; structured instance changes use the DOM `change` event above.
|
|
217
|
+
*/
|
|
218
|
+
export interface CeeEventHandler {
|
|
219
|
+
/** A diagnostic. `value` is the object it concerns, where there is one. */
|
|
220
|
+
trace?: (label: string, value: object | null) => void;
|
|
221
|
+
/** A failure worth surfacing — a template problem, a discarded value. */
|
|
222
|
+
error?: (label: string, value: object | null) => void;
|
|
223
|
+
/** Called after a field mutation actually changes the serialized instance. */
|
|
224
|
+
valueChanged?: (path: string[], value: unknown) => void;
|
|
225
|
+
/**
|
|
226
|
+
* @deprecated Never emitted. Listen for the structured DOM `change` event;
|
|
227
|
+
* this compatibility member will be removed in the next major release.
|
|
228
|
+
*/
|
|
229
|
+
message?: (message: string) => void;
|
|
230
|
+
/** Called once, after this element's first successful form render. */
|
|
231
|
+
ready?: () => void;
|
|
232
|
+
[event: string]: unknown;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* The custom element, as a host sees it.
|
|
236
|
+
*
|
|
237
|
+
* Registered as `cedar-embeddable-editor`. Configuration and the artifact inputs
|
|
238
|
+
* each take one assignment; a second is reported through the event handler and
|
|
239
|
+
* ignored, and the first accepted value stands. An unreadable instance is reported
|
|
240
|
+
* and does not spend its assignment, so the host may correct it. An artifact is a
|
|
241
|
+
* template and optionally an instance, so `templateAndInstanceObject` supplies
|
|
242
|
+
* between them what the two separate inputs do and cannot be combined with either.
|
|
243
|
+
*
|
|
244
|
+
* `eventHandler` is the exception, and deliberately: it may be replaced. The
|
|
245
|
+
* sentence above used to be written of every member, which was false for the
|
|
246
|
+
* handler and meaningless for the three read-only getters below.
|
|
247
|
+
*/
|
|
248
|
+
export interface CedarEmbeddableEditorElement extends HTMLElement {
|
|
249
|
+
/** Typed host mutation event; the inherited overloads still handle every other DOM event. */
|
|
250
|
+
addEventListener(type: 'change', listener: ((this: CedarEmbeddableEditorElement, event: CustomEvent<CeeChangeDetail>) => unknown) | null, options?: boolean | AddEventListenerOptions): void;
|
|
251
|
+
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, event: HTMLElementEventMap[K]) => unknown, options?: boolean | AddEventListenerOptions): void;
|
|
252
|
+
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
253
|
+
/** Typed counterpart to the specialized `change` listener overload. */
|
|
254
|
+
removeEventListener(type: 'change', listener: ((this: CedarEmbeddableEditorElement, event: CustomEvent<CeeChangeDetail>) => unknown) | null, options?: boolean | EventListenerOptions): void;
|
|
255
|
+
removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, event: HTMLElementEventMap[K]) => unknown, options?: boolean | EventListenerOptions): void;
|
|
256
|
+
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
|
257
|
+
/** Configuration. Assign once, before or after the artifact. */
|
|
258
|
+
config: CeeConfig;
|
|
259
|
+
/** The template to render, as a parsed CEDAR artifact. */
|
|
260
|
+
templateObject: CeeJsonObject;
|
|
261
|
+
/**
|
|
262
|
+
* An existing instance to load into the form.
|
|
263
|
+
*
|
|
264
|
+
* Independent of `templateObject`, and either may be assigned first: the form is
|
|
265
|
+
* not built until a template is present, so an instance supplied ahead of one
|
|
266
|
+
* waits rather than loading against nothing.
|
|
267
|
+
*/
|
|
268
|
+
instanceObject: CeeJsonObject;
|
|
269
|
+
/** Both at once, as `{ templateObject, instanceObject }`. */
|
|
270
|
+
templateAndInstanceObject: CeeTemplateAndInstance;
|
|
271
|
+
/**
|
|
272
|
+
* Host callbacks, which may be replaced: the last one assigned receives.
|
|
273
|
+
*
|
|
274
|
+
* Set-once protects the inputs that decide what the editor *is*, because the same
|
|
275
|
+
* assignments in a different order used to give a different editor. A handler
|
|
276
|
+
* decides nothing about the form, so nothing here needs an order to reason about,
|
|
277
|
+
* and sealing it would answer a host's second assignment by reporting the refusal
|
|
278
|
+
* *to the handler being replaced*. Replacing a callback slot is also what the DOM
|
|
279
|
+
* does everywhere else.
|
|
280
|
+
*
|
|
281
|
+
* Assign it before the configuration and the artifact if the diagnostics from those
|
|
282
|
+
* matter. A handler hears what CEE emits after it arrives, and CEE has already
|
|
283
|
+
* reported on a configuration by the time a handler assigned later is installed.
|
|
284
|
+
* Replacing one is traced, so a page whose messages stop arriving can see why.
|
|
285
|
+
*/
|
|
286
|
+
eventHandler: CeeEventHandler;
|
|
287
|
+
/** The instance as CEDAR JSON. Read-only. */
|
|
288
|
+
readonly currentMetadata: CeeJsonObject;
|
|
289
|
+
/** The instance as CEDAR YAML. Read-only. */
|
|
290
|
+
readonly currentMetadataYaml: string;
|
|
291
|
+
/** What CEE thinks of the instance. Read-only. */
|
|
292
|
+
readonly dataQualityReport: CeeDataQualityReport;
|
|
293
|
+
}
|
|
294
|
+
declare global {
|
|
295
|
+
interface HTMLElementTagNameMap {
|
|
296
|
+
'cedar-embeddable-editor': CedarEmbeddableEditorElement;
|
|
297
|
+
}
|
|
298
|
+
}
|