@ghentcdh/annotation-vue 0.0.1-alpha.3

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 ADDED
@@ -0,0 +1,263 @@
1
+ # @ghentcdh/annotation-vue
2
+
3
+ Vue 3 package for working with annotation definitions client-side — no NestJS backend required. Loads JSON annotation
4
+ configs, builds definitions via `@ghentcdh/annotation-core`, and exposes them as reactive Vue composables using
5
+ provide/inject.
6
+
7
+ ## Install
8
+
9
+ Peer dependencies:
10
+
11
+ ```
12
+ vue >= 3.5
13
+ @ghentcdh/annotation-core
14
+ @ghentcdh/w3c-utils
15
+ vue-router >= 4 (optional — only needed for router plugin)
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ ### Provide/inject pattern
21
+
22
+ Call `provideAnnotationDefinitions` once at the root component. All descendants use `useAnnotationDefinitions()` to
23
+ inject.
24
+
25
+ **Root component (provide):**
26
+
27
+ ```vue
28
+
29
+ <template>
30
+ <slot />
31
+ </template>
32
+
33
+ <script setup lang="ts">
34
+ import { provideAnnotationDefinitions } from '@ghentcdh/annotation-vue';
35
+
36
+ // import.meta.glob must be a string literal — call it here, pass result in
37
+ const resourceFolder = import.meta.glob('./configs/*.json', { eager: true });
38
+
39
+ const { definitions } = provideAnnotationDefinitions({
40
+ config: {
41
+ baseUrl: 'http://localhost:3000/',
42
+ app: 'myapp',
43
+ prefix: 'myapp',
44
+ isDev: true,
45
+ cacheTTLms: 0,
46
+ },
47
+ resourceFolder, // auto-loads definitions on creation
48
+ });
49
+ </script>
50
+ ```
51
+
52
+ **Child component (inject):**
53
+
54
+ ```vue
55
+
56
+ <template>
57
+ <div v-for="def in definitions" :key="def.id">
58
+ {{ def.label }}
59
+ </div>
60
+ </template>
61
+
62
+ <script setup lang="ts">
63
+ import { useAnnotationDefinitions } from '@ghentcdh/annotation-vue';
64
+
65
+ // No options needed — state is injected from ancestor
66
+ const { definitions, getDefinitionById } = useAnnotationDefinitions();
67
+ </script>
68
+ ```
69
+
70
+ ### provideAnnotationDefinitions options
71
+
72
+ | Option | Type | Required | Description |
73
+ |------------------------|----------------------------|----------|----------------------------------------------------|
74
+ | `config` | `AnnotationDefConfig` | yes | Base URL, app name, prefix, cache settings |
75
+ | `resourceFolder` | `GlobModules` | no | `import.meta.glob` result — auto-loads on creation |
76
+ | `createHighlightStyle` | `(def) => AnnotationStyle` | no | Custom style builder |
77
+ | `factory` | `ContextBuilderFactory` | no | Custom context builder factory |
78
+
79
+ ### Returned state (both provide and inject)
80
+
81
+ | Property | Type | Description |
82
+ |-----------------------|--------------------------------------------------------|-----------------------------------------|
83
+ | `definitions` | `ComputedRef<VueAnnotationDefinition[]>` | All definitions, reactively transformed |
84
+ | `definitionsMap` | `ComputedRef<Record<string, VueAnnotationDefinition>>` | Definitions keyed by ID |
85
+ | `getDefinitionById` | `(id: string) => VueAnnotationDefinition \| undefined` | Lookup by ID |
86
+ | `loadFromGlob` | `(modules: GlobModules) => void` | Load from `import.meta.glob` result |
87
+ | `loadFromConfigs` | `(configs: AnnotationJsonConfig[]) => void` | Load from config array |
88
+ | `loadFromDefinitions` | `(defs: CoreAnnotationDefinition[]) => void` | Load pre-built definitions |
89
+ | `service` | `AnnotationDefinitionService` | Underlying synchronous service |
90
+
91
+ ### Loading definitions manually
92
+
93
+ If you don't pass `resourceFolder`, load later:
94
+
95
+ ```ts
96
+ const state = provideAnnotationDefinitions({ config });
97
+
98
+ // From glob
99
+ const modules = import.meta.glob('./configs/*.json', { eager: true });
100
+ state.loadFromGlob(modules);
101
+
102
+ // From config array
103
+ state.loadFromConfigs([
104
+ { id: 'comment', name: 'Comment', color: '#ff0000' },
105
+ { id: 'entity', name: 'Entity', color: '#00ff00', allowedChildren: ['comment'] },
106
+ ]);
107
+
108
+ // From pre-built core definitions
109
+ state.loadFromDefinitions(coreDefinitions);
110
+ ```
111
+
112
+ ### VueAnnotationDefinition
113
+
114
+ Enriched version of core `AnnotationDefinition`, with:
115
+
116
+ - `label` — mapped from core `name`
117
+ - `style: AnnotationStyle` — built from `id`, `name`, `color`, `target`
118
+ - `schema: FormValidationDef` — wraps `ui_schema`, `json_schema`, `metadata_schema`
119
+ - `allowedChildren: KeyLabel[]` — string IDs resolved to `{ key, label, icon? }` objects
120
+ - `allowedLinks: KeyLabel[]` — same resolution
121
+ - `_core` — raw reference to the core `AnnotationDefinition`
122
+
123
+ ### Custom highlight styles
124
+
125
+ ```ts
126
+ provideAnnotationDefinitions({
127
+ config,
128
+ resourceFolder,
129
+ createHighlightStyle: (def) => ({
130
+ id: def.id,
131
+ name: def.name,
132
+ color: def.color,
133
+ target: def.target ?? 'highlight',
134
+ }),
135
+ });
136
+ ```
137
+
138
+ ### AnnotationDefinitionService
139
+
140
+ Synchronous, plain TS class (no NestJS dependency). Mirrors API service interface:
141
+
142
+ ```ts
143
+ import { AnnotationDefinitionService } from '@ghentcdh/annotation-vue';
144
+
145
+ const service = new AnnotationDefinitionService(definitions);
146
+
147
+ service.findAll(); // AnnotationDefinition[]
148
+ service.findById('comment'); // AnnotationDefinition | undefined
149
+ service.findAllGrouped(); // Record<string, AnnotationDefinition>
150
+ service.getAllContextBuilders(); // unknown[]
151
+ service.getContextBuilder(id); // unknown | undefined
152
+ service.setDefinitions(defs); // replace all definitions
153
+ ```
154
+
155
+ ### Router plugin (optional, requires `vue-router`)
156
+
157
+ Registers Vue Router routes that mirror the NestJS `AnnotationNamespaceController` endpoints. Useful for serving
158
+ annotation definitions client-side without a backend.
159
+
160
+ ```ts
161
+ import { createRouter, createWebHistory } from 'vue-router';
162
+ import {
163
+ AnnotationNamespacePlugin,
164
+ AnnotationDefinitionService,
165
+ } from '@ghentcdh/annotation-vue';
166
+
167
+ const service = new AnnotationDefinitionService(definitions);
168
+ const router = createRouter({ history: createWebHistory(), routes: [] });
169
+
170
+ // Option A: Vue plugin
171
+ app.use(AnnotationNamespacePlugin, {
172
+ router,
173
+ service,
174
+ basePath: '/ns', // default: '/ns'
175
+ config, // optional AnnotationDefConfig for AnnotationStyle context
176
+ });
177
+
178
+ // Option B: Direct install
179
+ import { installAnnotationNamespaceRoutes } from '@ghentcdh/annotation-vue';
180
+
181
+ installAnnotationNamespaceRoutes(router, service, { basePath: '/ns' });
182
+ ```
183
+
184
+ Registered routes:
185
+
186
+ | Path | Name | Description |
187
+ |-------------------------|-----------------------------|-------------------------------|
188
+ | `/ns` | `annotation-ns-all` | All definitions |
189
+ | `/ns/anno.jsonld` | `annotation-ns-all-jsonld` | All JSON-LD contexts |
190
+ | `/ns/:id.jsonld` | `annotation-ns-jsonld` | Single JSON-LD context |
191
+ | `/ns/:type/anno.jsonld` | `annotation-ns-type-jsonld` | JSON-LD + forms for type |
192
+ | `/ns/:id/schemas` | `annotation-ns-schemas` | Schemas subset for definition |
193
+ | `/ns/:id` | `annotation-ns-by-id` | Single definition |
194
+
195
+ ### Path helpers
196
+
197
+ Generate URL paths without installing routes:
198
+
199
+ ```ts
200
+ import { createAnnotationNamespacePaths } from '@ghentcdh/annotation-vue';
201
+
202
+ const paths = createAnnotationNamespacePaths('/ns');
203
+ paths.all; // '/ns'
204
+ paths.allJsonLd; // '/ns/anno.jsonld'
205
+ paths.byId('comment'); // '/ns/comment'
206
+ paths.jsonLdById('comment'); // '/ns/comment.jsonld'
207
+ paths.schemasById('comment'); // '/ns/comment/schemas'
208
+ ```
209
+
210
+ ## Resolve defintions from third party server
211
+
212
+ ```ts
213
+ │
214
+ │ // Simple — single app.use() │
215
+ │ app.use(AnnotationPlugin, { │
216
+ │ config: annotationDefConfig, │
217
+ │ router, │
218
+ │ definitionsUrl: '/api/ns', │
219
+ │
220
+ })
221
+ ; │
222
+ │ │
223
+ │ // Custom fetch (auth headers, axios, etc.) │
224
+ │ app.use(AnnotationPlugin, { │
225
+ │ config: annotationDefConfig, │
226
+ │ router, │
227
+ │ definitionsUrl: '/api/ns', │
228
+ │ fetchFn: async (url) => { │
229
+ │ const { data } = await axios.get(url, { headers: { Authorization: `Bearer ${token}` } }); │
230
+ │ return data; │
231
+ │
232
+ }, │
233
+ │
234
+ })
235
+ ;
236
+ ```
237
+
238
+ ## Package structure
239
+
240
+ ```
241
+ src/
242
+ index.ts # Barrel export
243
+ lib/
244
+ types/
245
+ annotation-vue.types.ts # KeyLabel, FormValidationDef, VueAnnotationDefinition
246
+ service/
247
+ annotation-definition.service.ts # Synchronous definition service
248
+ loader/
249
+ annotation-definition.loader.ts # import.meta.glob + config array loaders
250
+ composables/
251
+ useAnnotationDefinitions.ts # Provide/inject composable
252
+ router/
253
+ annotation-namespace.routes.ts # Route records + path helpers
254
+ annotation-namespace.plugin.ts # Vue Router plugin
255
+ ```
256
+
257
+ ## Build & test
258
+
259
+ ```sh
260
+ pnpm nx build annotation-vue
261
+ pnpm nx test annotation-vue
262
+ pnpm nx lint annotation-vue
263
+ ```
package/index.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export * from './lib/types/annotation-vue.types';
2
+ export { AnnotationDefinitionService } from './lib/service/annotation-definition.service';
3
+ export { type DefinitionsFetchFn, type GlobModules, loadAnnotationDefinitionsFromGlob, loadAnnotationDefinitionsFromConfigs, loadAnnotationDefinitionsFromUrl, } from './lib/loader/annotation-definition.loader';
4
+ export { type AnnotationDefinitionsState, type ProvideAnnotationDefinitionsOptions, provideAnnotationDefinitions, useAnnotationDefinitions, createAnnotationDefinitionsState, } from './lib/composables/useAnnotationDefinitions';
5
+ export { type AnnotationNamespaceRoutePaths, createAnnotationNamespacePaths, createAnnotationNamespaceRoutes, NAMESPACE_ROUTE_META, } from './lib/router/annotation-namespace.routes';
6
+ export { type AnnotationNamespacePluginOptions, type AnnotationPluginOptions, installAnnotationNamespaceRoutes, AnnotationNamespacePlugin, AnnotationPlugin, } from './lib/router/annotation-namespace.plugin';
package/index.js ADDED
@@ -0,0 +1,423 @@
1
+ import { z as e } from "zod";
2
+ import { contextBuilder as t } from "@ghentcdh/w3c-utils";
3
+ import { createHighlightStyle as n } from "@ghentcdh/annotated-text";
4
+ import { computed as r, defineComponent as i, h as a, inject as o, markRaw as s, provide as c, reactive as l, ref as u } from "vue";
5
+ //#region packages/annotation-vue/src/lib/service/annotation-definition.service.ts
6
+ var d = class {
7
+ definitions = [];
8
+ groupedDefinitions = {};
9
+ constructor(e = []) {
10
+ e.length && this.setDefinitions(e);
11
+ }
12
+ setDefinitions(e) {
13
+ this.definitions = e, this.groupedDefinitions = e.reduce((e, t) => (e[t.id] = t, e), {});
14
+ }
15
+ findAll() {
16
+ return this.definitions;
17
+ }
18
+ findById(e) {
19
+ return this.groupedDefinitions[e];
20
+ }
21
+ findAllGrouped() {
22
+ return this.groupedDefinitions;
23
+ }
24
+ getAllContextBuilders() {
25
+ return this.definitions.map((e) => e.context);
26
+ }
27
+ getContextBuilder(e) {
28
+ return this.findById(e)?.context;
29
+ }
30
+ }, f = "AnnotationMetadata", p = e.object({});
31
+ e.object({
32
+ id: e.string(),
33
+ name: e.string(),
34
+ columns: e.array(p),
35
+ json_schema: e.any().optional(),
36
+ json_ld: e.any().optional(),
37
+ ui_schema: e.any().optional(),
38
+ metadata_schema: e.any().optional(),
39
+ color: e.string(),
40
+ type: e.string().optional(),
41
+ icon: e.string().optional(),
42
+ isRoot: e.boolean().default(!0),
43
+ allowedChildren: e.array(e.string()).optional(),
44
+ allowedLinks: e.array(e.string()).optional(),
45
+ context: e.custom(),
46
+ target: e.enum([
47
+ "gutter",
48
+ "underline",
49
+ "highlight"
50
+ ]).optional()
51
+ });
52
+ //#endregion
53
+ //#region packages/annotation-core/src/lib/utils/annotation.context-builder.ts
54
+ var m = {
55
+ baseUrl: "http://localhost:3000/",
56
+ app: "ghentcdh",
57
+ prefix: "ghentcdh",
58
+ isDev: !1,
59
+ cacheTTLms: 1200 * 1e3
60
+ }, h = (e = {}) => {
61
+ let t = e.baseUrl ?? m.baseUrl, n = t.endsWith("/") ? t : `${t}/`, r = e.isDev ?? !1, i = r ? 0 : 1200 * 1e3;
62
+ return {
63
+ baseUrl: n,
64
+ contextUrl: `${n}ns/`,
65
+ app: e.app ?? m.app,
66
+ prefix: e.prefix ?? m.prefix,
67
+ isDev: r,
68
+ cacheTTLms: i
69
+ };
70
+ }, g = (e, n) => {
71
+ let { prefix: r, baseUrl: i, contextUrl: a } = h(n), o = f;
72
+ return t(r, i).setType(r, o).addPrefix(e, `${r}:${e}`).setContextUri(`${a}${e}.jsonld`);
73
+ }, _ = e.object({
74
+ id: e.string(),
75
+ name: e.string(),
76
+ target: e.enum([
77
+ "gutter",
78
+ "underline",
79
+ "highlight"
80
+ ]).optional().default("underline"),
81
+ color: e.string().optional()
82
+ }), v = "AnnotationStyle", y = (e) => {
83
+ let { prefix: n, baseUrl: r, contextUrl: i } = h(e);
84
+ return t(n, r).setType(n, v).setContextUri(`${i}${v}.jsonld`).parseZodSchema(_);
85
+ }, b = (e) => {
86
+ let t = {};
87
+ if (e.fieldInput) {
88
+ let { type: n, options: r } = e.fieldInput;
89
+ t.format = n, n === "autocomplete" && (t.dataField = "data", r.uri && (t.uri = r.uri), r.resource && (t.resource = r.resource), r.valueKey && (t.valueKey = r.valueKey), r.labelKey && (t.labelKey = r.labelKey), r.enableCreate !== void 0 && (t.enableCreate = r.enableCreate));
90
+ }
91
+ return {
92
+ type: "Control",
93
+ scope: `#/properties/${e.id}`,
94
+ options: t
95
+ };
96
+ }, x = (e) => ({
97
+ type: "TextCell",
98
+ scope: `#/properties/${e.id}`,
99
+ options: {
100
+ format: "keyValue",
101
+ key: e.fieldInput?.options?.labelKey ?? e.displayKey ?? "label"
102
+ }
103
+ }), S = (e) => ({
104
+ type: "GridLayout",
105
+ elements: e.filter((e) => !e.hiddenInForm).map(b),
106
+ options: {}
107
+ }), C = (e) => ({
108
+ type: "GridLayout",
109
+ elements: e.filter((e) => !e.hiddenInMetadata).map(x),
110
+ options: {}
111
+ }), w = (t) => {
112
+ if (t.type === "object" && t.properties) {
113
+ let n = {};
114
+ for (let [e, r] of Object.entries(t.properties)) n[e] = w(r);
115
+ return e.object(n);
116
+ }
117
+ return e.string();
118
+ }, T = (t, n, r) => {
119
+ let i = g(t, r), a = n.columns ?? [];
120
+ if (!a.length) return i;
121
+ let o = {};
122
+ for (let e of a) e.type && (o[e.id] = w(e.type));
123
+ return Object.keys(o).length ? i.parseZodSchema(e.object(o)) : i;
124
+ }, E = (e, t, n = T) => {
125
+ let r = n(e.id, e, t), i = e.columns ?? [], a = i.length > 0, o = e.ui_schema ?? (a ? S(i) : void 0), s = e.metadata_schema ?? (a ? C(i) : void 0), c = {
126
+ id: e.id,
127
+ name: e.name,
128
+ color: e.color,
129
+ isRoot: e.isRoot ?? !0,
130
+ columns: i,
131
+ context: r,
132
+ json_ld: r.toJsonLdContext(),
133
+ json_schema: o ? r.toJsonSchema() : null
134
+ };
135
+ return o && (c.ui_schema = o), s && (c.metadata_schema = s), e.type && (c.type = e.type), e.icon && (c.icon = e.icon), e.target && (c.target = e.target), e.allowedChildren && (c.allowedChildren = e.allowedChildren), e.allowedLinks && (c.allowedLinks = e.allowedLinks), c;
136
+ }, D = (e, t, n) => e.map((e) => E(e, t, n)), O = (e) => "default" in e ? e.default : e, k = (e, t, n) => A(Object.values(e).map(O), t, n), A = (e, t, n) => D(e, t, n), j = async (e) => {
137
+ let t = await fetch(e);
138
+ if (!t.ok) throw Error(`Failed to fetch annotation definitions: ${t.status} ${t.statusText}`);
139
+ return t.json();
140
+ }, M = async (e, t, n, r = j) => A(await r(e), t, n), N = Symbol("annotation-definitions"), P = (e, t) => e ? e.reduce((e, n) => {
141
+ let r = t[n];
142
+ if (r) {
143
+ let t = {
144
+ key: r.id,
145
+ label: r.name
146
+ };
147
+ r.icon && (t.icon = r.icon), e.push(t);
148
+ }
149
+ return e;
150
+ }, []) : [], F = (e, t, n, r) => {
151
+ let i = {
152
+ uiSchema: e.ui_schema ?? null,
153
+ jsonSchema: e.json_schema ?? null,
154
+ metaDataSchema: e.metadata_schema ?? null,
155
+ validation: (e) => e
156
+ };
157
+ return {
158
+ id: e.id,
159
+ name: e.name,
160
+ label: e.name,
161
+ color: e.color,
162
+ style: {
163
+ default: n(e.color),
164
+ active: r(e.color)
165
+ },
166
+ schema: i,
167
+ allowedChildren: P(e.allowedChildren, t),
168
+ allowedLinks: P(e.allowedLinks, t),
169
+ isRoot: e.isRoot ?? !0,
170
+ icon: e.icon,
171
+ type: e.type,
172
+ target: e.target,
173
+ context: e.context,
174
+ _core: e
175
+ };
176
+ }, I = (e) => {
177
+ let { config: t, factory: i } = e, a = e.createHighlightStyle ?? n, o = e.activeHighlightStyle ?? a, c = s(new d()), f = u([]), p = r(() => {
178
+ let e = c.findAllGrouped();
179
+ return f.value.map((t) => F(t, e, a, o));
180
+ }), m = r(() => p.value.reduce((e, t) => (e[t.id] = t, e), {})), h = (e) => m.value[e], g = (e) => {
181
+ c.setDefinitions(e), f.value = e;
182
+ }, _ = (e) => {
183
+ g(k(e, t, i));
184
+ }, v = (e) => {
185
+ g(A(e, t, i));
186
+ }, y = u(!1), b = u(null);
187
+ return l({
188
+ configuration: t,
189
+ definitions: p,
190
+ definitionsMap: m,
191
+ getDefinitionById: h,
192
+ loadFromGlob: _,
193
+ loadFromConfigs: v,
194
+ loadFromDefinitions: g,
195
+ loadFromUrl: async (e, n) => {
196
+ y.value = !0, b.value = null;
197
+ try {
198
+ g(await M(e, t, i, n));
199
+ } catch (e) {
200
+ b.value = e instanceof Error ? e : Error(String(e));
201
+ } finally {
202
+ y.value = !1;
203
+ }
204
+ },
205
+ loading: y,
206
+ error: b,
207
+ service: c
208
+ });
209
+ }, L = (e) => {
210
+ let t = I(e);
211
+ return e.resourceFolder && t.loadFromGlob(e.resourceFolder), e.definitionsUrl && t.loadFromUrl(e.definitionsUrl, e.fetchFn), c(N, t), t;
212
+ }, R = () => {
213
+ let e = o(N);
214
+ if (!e) throw Error("useAnnotationDefinitions() must be called inside a component that called provideAnnotationDefinitions()");
215
+ return e;
216
+ }, z = (e = "/ns") => {
217
+ let t = e.endsWith("/") ? e.slice(0, -1) : e;
218
+ return {
219
+ all: t,
220
+ allJsonLd: `${t}/anno.jsonld`,
221
+ byId: (e) => `${t}/${e}`,
222
+ jsonLdById: (e) => `${t}/${e}.jsonld`,
223
+ schemasById: (e) => `${t}/${e}/schemas`,
224
+ typeJsonLd: (e) => `${t}/${e}/anno.jsonld`
225
+ };
226
+ }, B = i({
227
+ name: "JsonView",
228
+ props: {
229
+ data: {
230
+ type: [
231
+ Object,
232
+ Array,
233
+ String,
234
+ Number
235
+ ],
236
+ default: null
237
+ },
238
+ title: {
239
+ type: String,
240
+ required: !1,
241
+ default: ""
242
+ }
243
+ },
244
+ setup(e) {
245
+ let t = r(() => JSON.stringify(e.data, null, 2)), n = r(() => !1), i = () => {
246
+ navigator.clipboard.writeText(t.value);
247
+ }, o = () => {
248
+ let n = new Blob([t.value], { type: "application/json" }), r = URL.createObjectURL(n), i = document.createElement("a");
249
+ i.href = r, i.download = `${e.title || "data"}.json`, i.click(), URL.revokeObjectURL(r);
250
+ };
251
+ return () => a("div", { style: {
252
+ fontFamily: "monospace",
253
+ fontSize: "13px",
254
+ padding: "16px",
255
+ maxWidth: "100%",
256
+ boxSizing: "border-box"
257
+ } }, [a("div", { style: {
258
+ display: "flex",
259
+ alignItems: "center",
260
+ gap: "8px",
261
+ marginBottom: "12px",
262
+ flexWrap: "wrap"
263
+ } }, [
264
+ e.title ? a("span", { style: {
265
+ fontWeight: "bold",
266
+ fontSize: "14px",
267
+ marginRight: "auto"
268
+ } }, e.title) : null,
269
+ a("button", {
270
+ onClick: i,
271
+ style: {
272
+ cursor: "pointer",
273
+ padding: "4px 10px",
274
+ fontSize: "12px",
275
+ border: "1px solid #ccc",
276
+ borderRadius: "4px",
277
+ background: "#f5f5f5"
278
+ }
279
+ }, n.value ? "Copied" : "Copy"),
280
+ a("button", {
281
+ onClick: o,
282
+ style: {
283
+ cursor: "pointer",
284
+ padding: "4px 10px",
285
+ fontSize: "12px",
286
+ border: "1px solid #ccc",
287
+ borderRadius: "4px",
288
+ background: "#f5f5f5"
289
+ }
290
+ }, "Download")
291
+ ]), a("pre", { style: {
292
+ margin: 0,
293
+ whiteSpace: "pre-wrap",
294
+ wordBreak: "break-word",
295
+ background: "#fafafa",
296
+ border: "1px solid #e0e0e0",
297
+ borderRadius: "4px",
298
+ padding: "12px",
299
+ overflow: "auto"
300
+ } }, t.value)]);
301
+ }
302
+ }), V = {
303
+ namespace: !0,
304
+ layout: "blank"
305
+ }, H = (e, t, n) => {
306
+ let r = e.endsWith("/") ? e.slice(0, -1) : e, i = { ...V };
307
+ return [
308
+ {
309
+ path: `${r}/anno.jsonld`,
310
+ name: "annotation-ns-all-jsonld",
311
+ component: B,
312
+ meta: i,
313
+ props: () => ({
314
+ title: "All JSON-LD contexts",
315
+ data: t.getAllContextBuilders().map((e) => e.toJsonLdContext())
316
+ })
317
+ },
318
+ {
319
+ path: `${r}/:id.jsonld`,
320
+ name: "annotation-ns-jsonld",
321
+ component: B,
322
+ meta: i,
323
+ props: (e) => {
324
+ let r = e.params.id;
325
+ if (r === "AnnotationStyle" && n) return {
326
+ title: `${r}.jsonld`,
327
+ data: y(n).toJsonLdContext()
328
+ };
329
+ let i = t.findById(r);
330
+ return {
331
+ title: `${r}.jsonld`,
332
+ data: i?.json_ld ?? null
333
+ };
334
+ }
335
+ },
336
+ {
337
+ path: `${r}/:type/anno.jsonld`,
338
+ name: "annotation-ns-type-jsonld",
339
+ component: B,
340
+ meta: i,
341
+ props: (e) => {
342
+ let n = e.params.type, r = t.getContextBuilder(n);
343
+ return r ? {
344
+ title: `${n}/anno.jsonld`,
345
+ data: {
346
+ jsonLd: r.toJsonLdContext(),
347
+ forms: r.toJsonSchema()
348
+ }
349
+ } : {
350
+ title: n,
351
+ data: null
352
+ };
353
+ }
354
+ },
355
+ {
356
+ path: `${r}/:id/schemas`,
357
+ name: "annotation-ns-schemas",
358
+ component: B,
359
+ meta: i,
360
+ props: (e) => {
361
+ let n = e.params.id, r = t.findById(n);
362
+ return r ? {
363
+ title: `${n}/schemas`,
364
+ data: {
365
+ id: r.id,
366
+ name: r.name,
367
+ json_schema: r.json_schema,
368
+ ui_schema: r.ui_schema,
369
+ metadata_schema: r.metadata_schema,
370
+ columns: r.columns,
371
+ isRoot: r.isRoot,
372
+ allowedChildren: r.allowedChildren,
373
+ allowedLinks: r.allowedLinks,
374
+ type: r.type,
375
+ icon: r.icon,
376
+ target: r.target
377
+ }
378
+ } : {
379
+ title: n,
380
+ data: null
381
+ };
382
+ }
383
+ },
384
+ {
385
+ path: `${r}/:id`,
386
+ name: "annotation-ns-by-id",
387
+ component: B,
388
+ meta: i,
389
+ props: (e) => {
390
+ let n = e.params.id;
391
+ return {
392
+ title: n,
393
+ data: t.findById(n) ?? null
394
+ };
395
+ }
396
+ },
397
+ {
398
+ path: r,
399
+ name: "annotation-ns-all",
400
+ component: B,
401
+ meta: i,
402
+ props: () => ({
403
+ title: "All definitions",
404
+ data: t.findAll()
405
+ })
406
+ }
407
+ ];
408
+ }, U = (e, t, n) => {
409
+ H(n?.basePath ?? "/ns", t, n?.config).forEach((t) => e.addRoute(t));
410
+ }, W = { install(e, t) {
411
+ U(t.router, t.service, {
412
+ basePath: t.basePath,
413
+ config: t.config
414
+ });
415
+ } }, G = { install(e, t) {
416
+ let n = I(t);
417
+ return t.resourceFolder && n.loadFromGlob(t.resourceFolder), t.definitionsUrl && n.loadFromUrl(t.definitionsUrl, t.fetchFn), e.provide(N, n), U(t.router, n.service, {
418
+ basePath: t.basePath,
419
+ config: t.config
420
+ }), n;
421
+ } };
422
+ //#endregion
423
+ export { d as AnnotationDefinitionService, W as AnnotationNamespacePlugin, G as AnnotationPlugin, V as NAMESPACE_ROUTE_META, I as createAnnotationDefinitionsState, z as createAnnotationNamespacePaths, H as createAnnotationNamespaceRoutes, U as installAnnotationNamespaceRoutes, A as loadAnnotationDefinitionsFromConfigs, k as loadAnnotationDefinitionsFromGlob, M as loadAnnotationDefinitionsFromUrl, L as provideAnnotationDefinitions, R as useAnnotationDefinitions };
package/index.umd.cjs ADDED
@@ -0,0 +1 @@
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("zod"),require("@ghentcdh/w3c-utils"),require("@ghentcdh/annotated-text"),require("vue")):typeof define==`function`&&define.amd?define([`exports`,`zod`,`@ghentcdh/w3c-utils`,`@ghentcdh/annotated-text`,`vue`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e[`annotation-vue`]={},e.zod,e._ghentcdh_w3c_utils,e._ghentcdh_annotated_text,e.vue))})(this,function(e,t,n,r,i){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var a=class{definitions=[];groupedDefinitions={};constructor(e=[]){e.length&&this.setDefinitions(e)}setDefinitions(e){this.definitions=e,this.groupedDefinitions=e.reduce((e,t)=>(e[t.id]=t,e),{})}findAll(){return this.definitions}findById(e){return this.groupedDefinitions[e]}findAllGrouped(){return this.groupedDefinitions}getAllContextBuilders(){return this.definitions.map(e=>e.context)}getContextBuilder(e){return this.findById(e)?.context}},o=`AnnotationMetadata`,s=t.z.object({});t.z.object({id:t.z.string(),name:t.z.string(),columns:t.z.array(s),json_schema:t.z.any().optional(),json_ld:t.z.any().optional(),ui_schema:t.z.any().optional(),metadata_schema:t.z.any().optional(),color:t.z.string(),type:t.z.string().optional(),icon:t.z.string().optional(),isRoot:t.z.boolean().default(!0),allowedChildren:t.z.array(t.z.string()).optional(),allowedLinks:t.z.array(t.z.string()).optional(),context:t.z.custom(),target:t.z.enum([`gutter`,`underline`,`highlight`]).optional()});var c={baseUrl:`http://localhost:3000/`,app:`ghentcdh`,prefix:`ghentcdh`,isDev:!1,cacheTTLms:1200*1e3},l=(e={})=>{let t=e.baseUrl??c.baseUrl,n=t.endsWith(`/`)?t:`${t}/`,r=e.isDev??!1,i=r?0:1200*1e3;return{baseUrl:n,contextUrl:`${n}ns/`,app:e.app??c.app,prefix:e.prefix??c.prefix,isDev:r,cacheTTLms:i}},u=(e,t)=>{let{prefix:r,baseUrl:i,contextUrl:a}=l(t),s=o;return(0,n.contextBuilder)(r,i).setType(r,s).addPrefix(e,`${r}:${e}`).setContextUri(`${a}${e}.jsonld`)},d=t.z.object({id:t.z.string(),name:t.z.string(),target:t.z.enum([`gutter`,`underline`,`highlight`]).optional().default(`underline`),color:t.z.string().optional()}),f=`AnnotationStyle`,p=e=>{let{prefix:t,baseUrl:r,contextUrl:i}=l(e);return(0,n.contextBuilder)(t,r).setType(t,f).setContextUri(`${i}${f}.jsonld`).parseZodSchema(d)},m=e=>{let t={};if(e.fieldInput){let{type:n,options:r}=e.fieldInput;t.format=n,n===`autocomplete`&&(t.dataField=`data`,r.uri&&(t.uri=r.uri),r.resource&&(t.resource=r.resource),r.valueKey&&(t.valueKey=r.valueKey),r.labelKey&&(t.labelKey=r.labelKey),r.enableCreate!==void 0&&(t.enableCreate=r.enableCreate))}return{type:`Control`,scope:`#/properties/${e.id}`,options:t}},h=e=>({type:`TextCell`,scope:`#/properties/${e.id}`,options:{format:`keyValue`,key:e.fieldInput?.options?.labelKey??e.displayKey??`label`}}),g=e=>({type:`GridLayout`,elements:e.filter(e=>!e.hiddenInForm).map(m),options:{}}),_=e=>({type:`GridLayout`,elements:e.filter(e=>!e.hiddenInMetadata).map(h),options:{}}),v=e=>{if(e.type===`object`&&e.properties){let n={};for(let[t,r]of Object.entries(e.properties))n[t]=v(r);return t.z.object(n)}return t.z.string()},y=(e,n,r)=>{let i=u(e,r),a=n.columns??[];if(!a.length)return i;let o={};for(let e of a)e.type&&(o[e.id]=v(e.type));return Object.keys(o).length?i.parseZodSchema(t.z.object(o)):i},b=(e,t,n=y)=>{let r=n(e.id,e,t),i=e.columns??[],a=i.length>0,o=e.ui_schema??(a?g(i):void 0),s=e.metadata_schema??(a?_(i):void 0),c={id:e.id,name:e.name,color:e.color,isRoot:e.isRoot??!0,columns:i,context:r,json_ld:r.toJsonLdContext(),json_schema:o?r.toJsonSchema():null};return o&&(c.ui_schema=o),s&&(c.metadata_schema=s),e.type&&(c.type=e.type),e.icon&&(c.icon=e.icon),e.target&&(c.target=e.target),e.allowedChildren&&(c.allowedChildren=e.allowedChildren),e.allowedLinks&&(c.allowedLinks=e.allowedLinks),c},x=(e,t,n)=>e.map(e=>b(e,t,n)),S=e=>`default`in e?e.default:e,C=(e,t,n)=>w(Object.values(e).map(S),t,n),w=(e,t,n)=>x(e,t,n),T=async e=>{let t=await fetch(e);if(!t.ok)throw Error(`Failed to fetch annotation definitions: ${t.status} ${t.statusText}`);return t.json()},E=async(e,t,n,r=T)=>w(await r(e),t,n),D=Symbol(`annotation-definitions`),O=(e,t)=>e?e.reduce((e,n)=>{let r=t[n];if(r){let t={key:r.id,label:r.name};r.icon&&(t.icon=r.icon),e.push(t)}return e},[]):[],k=(e,t,n,r)=>{let i={uiSchema:e.ui_schema??null,jsonSchema:e.json_schema??null,metaDataSchema:e.metadata_schema??null,validation:e=>e};return{id:e.id,name:e.name,label:e.name,color:e.color,style:{default:n(e.color),active:r(e.color)},schema:i,allowedChildren:O(e.allowedChildren,t),allowedLinks:O(e.allowedLinks,t),isRoot:e.isRoot??!0,icon:e.icon,type:e.type,target:e.target,context:e.context,_core:e}},A=e=>{let{config:t,factory:n}=e,o=e.createHighlightStyle??r.createHighlightStyle,s=e.activeHighlightStyle??o,c=(0,i.markRaw)(new a),l=(0,i.ref)([]),u=(0,i.computed)(()=>{let e=c.findAllGrouped();return l.value.map(t=>k(t,e,o,s))}),d=(0,i.computed)(()=>u.value.reduce((e,t)=>(e[t.id]=t,e),{})),f=e=>d.value[e],p=e=>{c.setDefinitions(e),l.value=e},m=e=>{p(C(e,t,n))},h=e=>{p(w(e,t,n))},g=(0,i.ref)(!1),_=(0,i.ref)(null);return(0,i.reactive)({configuration:t,definitions:u,definitionsMap:d,getDefinitionById:f,loadFromGlob:m,loadFromConfigs:h,loadFromDefinitions:p,loadFromUrl:async(e,r)=>{g.value=!0,_.value=null;try{p(await E(e,t,n,r))}catch(e){_.value=e instanceof Error?e:Error(String(e))}finally{g.value=!1}},loading:g,error:_,service:c})},j=e=>{let t=A(e);return e.resourceFolder&&t.loadFromGlob(e.resourceFolder),e.definitionsUrl&&t.loadFromUrl(e.definitionsUrl,e.fetchFn),(0,i.provide)(D,t),t},M=()=>{let e=(0,i.inject)(D);if(!e)throw Error(`useAnnotationDefinitions() must be called inside a component that called provideAnnotationDefinitions()`);return e},N=(e=`/ns`)=>{let t=e.endsWith(`/`)?e.slice(0,-1):e;return{all:t,allJsonLd:`${t}/anno.jsonld`,byId:e=>`${t}/${e}`,jsonLdById:e=>`${t}/${e}.jsonld`,schemasById:e=>`${t}/${e}/schemas`,typeJsonLd:e=>`${t}/${e}/anno.jsonld`}},P=(0,i.defineComponent)({name:`JsonView`,props:{data:{type:[Object,Array,String,Number],default:null},title:{type:String,required:!1,default:``}},setup(e){let t=(0,i.computed)(()=>JSON.stringify(e.data,null,2)),n=(0,i.computed)(()=>!1),r=()=>{navigator.clipboard.writeText(t.value)},a=()=>{let n=new Blob([t.value],{type:`application/json`}),r=URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=`${e.title||`data`}.json`,i.click(),URL.revokeObjectURL(r)};return()=>(0,i.h)(`div`,{style:{fontFamily:`monospace`,fontSize:`13px`,padding:`16px`,maxWidth:`100%`,boxSizing:`border-box`}},[(0,i.h)(`div`,{style:{display:`flex`,alignItems:`center`,gap:`8px`,marginBottom:`12px`,flexWrap:`wrap`}},[e.title?(0,i.h)(`span`,{style:{fontWeight:`bold`,fontSize:`14px`,marginRight:`auto`}},e.title):null,(0,i.h)(`button`,{onClick:r,style:{cursor:`pointer`,padding:`4px 10px`,fontSize:`12px`,border:`1px solid #ccc`,borderRadius:`4px`,background:`#f5f5f5`}},n.value?`Copied`:`Copy`),(0,i.h)(`button`,{onClick:a,style:{cursor:`pointer`,padding:`4px 10px`,fontSize:`12px`,border:`1px solid #ccc`,borderRadius:`4px`,background:`#f5f5f5`}},`Download`)]),(0,i.h)(`pre`,{style:{margin:0,whiteSpace:`pre-wrap`,wordBreak:`break-word`,background:`#fafafa`,border:`1px solid #e0e0e0`,borderRadius:`4px`,padding:`12px`,overflow:`auto`}},t.value)])}}),F={namespace:!0,layout:`blank`},I=(e,t,n)=>{let r=e.endsWith(`/`)?e.slice(0,-1):e,i={...F};return[{path:`${r}/anno.jsonld`,name:`annotation-ns-all-jsonld`,component:P,meta:i,props:()=>({title:`All JSON-LD contexts`,data:t.getAllContextBuilders().map(e=>e.toJsonLdContext())})},{path:`${r}/:id.jsonld`,name:`annotation-ns-jsonld`,component:P,meta:i,props:e=>{let r=e.params.id;if(r===`AnnotationStyle`&&n)return{title:`${r}.jsonld`,data:p(n).toJsonLdContext()};let i=t.findById(r);return{title:`${r}.jsonld`,data:i?.json_ld??null}}},{path:`${r}/:type/anno.jsonld`,name:`annotation-ns-type-jsonld`,component:P,meta:i,props:e=>{let n=e.params.type,r=t.getContextBuilder(n);return r?{title:`${n}/anno.jsonld`,data:{jsonLd:r.toJsonLdContext(),forms:r.toJsonSchema()}}:{title:n,data:null}}},{path:`${r}/:id/schemas`,name:`annotation-ns-schemas`,component:P,meta:i,props:e=>{let n=e.params.id,r=t.findById(n);return r?{title:`${n}/schemas`,data:{id:r.id,name:r.name,json_schema:r.json_schema,ui_schema:r.ui_schema,metadata_schema:r.metadata_schema,columns:r.columns,isRoot:r.isRoot,allowedChildren:r.allowedChildren,allowedLinks:r.allowedLinks,type:r.type,icon:r.icon,target:r.target}}:{title:n,data:null}}},{path:`${r}/:id`,name:`annotation-ns-by-id`,component:P,meta:i,props:e=>{let n=e.params.id;return{title:n,data:t.findById(n)??null}}},{path:r,name:`annotation-ns-all`,component:P,meta:i,props:()=>({title:`All definitions`,data:t.findAll()})}]},L=(e,t,n)=>{I(n?.basePath??`/ns`,t,n?.config).forEach(t=>e.addRoute(t))};e.AnnotationDefinitionService=a,e.AnnotationNamespacePlugin={install(e,t){L(t.router,t.service,{basePath:t.basePath,config:t.config})}},e.AnnotationPlugin={install(e,t){let n=A(t);return t.resourceFolder&&n.loadFromGlob(t.resourceFolder),t.definitionsUrl&&n.loadFromUrl(t.definitionsUrl,t.fetchFn),e.provide(D,n),L(t.router,n.service,{basePath:t.basePath,config:t.config}),n}},e.NAMESPACE_ROUTE_META=F,e.createAnnotationDefinitionsState=A,e.createAnnotationNamespacePaths=N,e.createAnnotationNamespaceRoutes=I,e.installAnnotationNamespaceRoutes=L,e.loadAnnotationDefinitionsFromConfigs=w,e.loadAnnotationDefinitionsFromGlob=C,e.loadAnnotationDefinitionsFromUrl=E,e.provideAnnotationDefinitions=j,e.useAnnotationDefinitions=M});
@@ -0,0 +1,39 @@
1
+ import { InjectionKey } from 'vue';
2
+ import { AnnotationDefConfig, AnnotationDefinition as CoreAnnotationDefinition, AnnotationJsonConfig, ContextBuilderFactory } from '@ghentcdh/annotation-core';
3
+ import { createHighlightStyle } from '@ghentcdh/annotated-text';
4
+ import { VueAnnotationDefinition } from '../types/annotation-vue.types';
5
+ import { AnnotationDefinitionService } from '../service/annotation-definition.service';
6
+ import { DefinitionsFetchFn, GlobModules } from '../loader/annotation-definition.loader';
7
+ export type AnnotationDefinitionsState = {
8
+ configuration: AnnotationDefConfig;
9
+ definitions: VueAnnotationDefinition[];
10
+ definitionsMap: Record<string, VueAnnotationDefinition>;
11
+ getDefinitionById: (id: string) => VueAnnotationDefinition | undefined;
12
+ loadFromGlob: (modules: GlobModules) => void;
13
+ loadFromConfigs: (configs: AnnotationJsonConfig[]) => void;
14
+ loadFromDefinitions: (defs: CoreAnnotationDefinition[]) => void;
15
+ loadFromUrl: (url: string, fetchFn?: DefinitionsFetchFn) => Promise<void>;
16
+ loading: boolean;
17
+ error: Error | null;
18
+ service: AnnotationDefinitionService;
19
+ };
20
+ export type ProvideAnnotationDefinitionsOptions = {
21
+ config: AnnotationDefConfig;
22
+ resourceFolder?: GlobModules;
23
+ createHighlightStyle?: typeof createHighlightStyle;
24
+ activeHighlightStyle?: typeof createHighlightStyle;
25
+ factory?: ContextBuilderFactory;
26
+ definitionsUrl?: string;
27
+ fetchFn?: DefinitionsFetchFn;
28
+ };
29
+ export declare const ANNOTATION_DEFINITIONS_KEY: InjectionKey<AnnotationDefinitionsState>;
30
+ export declare const createAnnotationDefinitionsState: (options: ProvideAnnotationDefinitionsOptions) => AnnotationDefinitionsState;
31
+ /**
32
+ * Called once at root — creates state, provides to descendants.
33
+ * If `resourceFolder` given, loads definitions immediately.
34
+ */
35
+ export declare const provideAnnotationDefinitions: (options: ProvideAnnotationDefinitionsOptions) => AnnotationDefinitionsState;
36
+ /**
37
+ * Called in child components — injects state from ancestor.
38
+ */
39
+ export declare const useAnnotationDefinitions: () => AnnotationDefinitionsState;
@@ -0,0 +1,10 @@
1
+ import { AnnotationJsonConfig, AnnotationDefConfig, AnnotationDefinition, ContextBuilderFactory } from '@ghentcdh/annotation-core';
2
+ type GlobModule = {
3
+ default: AnnotationJsonConfig;
4
+ } | AnnotationJsonConfig;
5
+ export type GlobModules = Record<string, GlobModule>;
6
+ export declare const loadAnnotationDefinitionsFromGlob: (modules: GlobModules, config: AnnotationDefConfig, factory?: ContextBuilderFactory) => AnnotationDefinition[];
7
+ export declare const loadAnnotationDefinitionsFromConfigs: (configs: AnnotationJsonConfig[], config: AnnotationDefConfig, factory?: ContextBuilderFactory) => AnnotationDefinition[];
8
+ export type DefinitionsFetchFn = (url: string) => Promise<AnnotationJsonConfig[]>;
9
+ export declare const loadAnnotationDefinitionsFromUrl: (url: string, config: AnnotationDefConfig, factory?: ContextBuilderFactory, fetchFn?: DefinitionsFetchFn) => Promise<AnnotationDefinition[]>;
10
+ export {};
@@ -0,0 +1,23 @@
1
+ import { Plugin } from 'vue';
2
+ import { Router } from 'vue-router';
3
+ import { AnnotationDefConfig } from '@ghentcdh/annotation-core';
4
+ import { AnnotationDefinitionService } from '../service/annotation-definition.service';
5
+ import { ProvideAnnotationDefinitionsOptions } from '../composables/useAnnotationDefinitions';
6
+ export type AnnotationNamespacePluginOptions = {
7
+ router: Router;
8
+ service: AnnotationDefinitionService;
9
+ basePath?: string;
10
+ config?: AnnotationDefConfig;
11
+ };
12
+ export type AnnotationPluginOptions = ProvideAnnotationDefinitionsOptions & {
13
+ router: Router;
14
+ basePath?: string;
15
+ };
16
+ export declare const installAnnotationNamespaceRoutes: (router: Router, service: AnnotationDefinitionService, options?: {
17
+ basePath?: string;
18
+ config?: AnnotationDefConfig;
19
+ }) => void;
20
+ export declare const AnnotationNamespacePlugin: Plugin<[
21
+ AnnotationNamespacePluginOptions
22
+ ]>;
23
+ export declare const AnnotationPlugin: Plugin<[AnnotationPluginOptions]>;
@@ -0,0 +1,17 @@
1
+ import { RouteRecordRaw } from 'vue-router';
2
+ import { AnnotationDefConfig } from '@ghentcdh/annotation-core';
3
+ import { AnnotationDefinitionService } from '../service/annotation-definition.service';
4
+ export type AnnotationNamespaceRoutePaths = {
5
+ all: string;
6
+ allJsonLd: string;
7
+ byId: (id: string) => string;
8
+ jsonLdById: (id: string) => string;
9
+ schemasById: (id: string) => string;
10
+ typeJsonLd: (type: string) => string;
11
+ };
12
+ export declare const createAnnotationNamespacePaths: (basePath?: string) => AnnotationNamespaceRoutePaths;
13
+ export declare const NAMESPACE_ROUTE_META: {
14
+ readonly namespace: true;
15
+ readonly layout: "blank";
16
+ };
17
+ export declare const createAnnotationNamespaceRoutes: (basePath: string, service: AnnotationDefinitionService, config?: AnnotationDefConfig) => RouteRecordRaw[];
@@ -0,0 +1,12 @@
1
+ import { AnnotationDefinition } from '@ghentcdh/annotation-core';
2
+ export declare class AnnotationDefinitionService {
3
+ private definitions;
4
+ private groupedDefinitions;
5
+ constructor(definitions?: AnnotationDefinition[]);
6
+ setDefinitions(definitions: AnnotationDefinition[]): void;
7
+ findAll(): AnnotationDefinition[];
8
+ findById(id: string): AnnotationDefinition | undefined;
9
+ findAllGrouped(): Record<string, AnnotationDefinition>;
10
+ getAllContextBuilders(): unknown[];
11
+ getContextBuilder(type: string): unknown | undefined;
12
+ }
@@ -0,0 +1,30 @@
1
+ import { AnnotationDefinition as CoreAnnotationDefinition } from '@ghentcdh/annotation-core';
2
+ import { ContextBuilder } from '@ghentcdh/w3c-utils';
3
+ import { CustomAnnotationStyle } from '@ghentcdh/annotated-text';
4
+ export type KeyLabel<KEY = string> = {
5
+ key: KEY;
6
+ label: string;
7
+ icon?: string;
8
+ };
9
+ export type FormValidationDef = {
10
+ uiSchema: unknown;
11
+ jsonSchema: unknown;
12
+ metaDataSchema: unknown;
13
+ validation: (value: unknown) => unknown;
14
+ };
15
+ export type VueAnnotationDefinition = {
16
+ id: string;
17
+ name: string;
18
+ label: string;
19
+ color: string;
20
+ style: CustomAnnotationStyle;
21
+ schema: FormValidationDef;
22
+ allowedChildren: KeyLabel[];
23
+ allowedLinks: KeyLabel[];
24
+ isRoot: boolean;
25
+ icon?: string;
26
+ type?: string;
27
+ target?: 'gutter' | 'underline' | 'highlight';
28
+ context: ContextBuilder;
29
+ _core: CoreAnnotationDefinition;
30
+ };
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@ghentcdh/annotation-vue",
3
+ "version": "0.0.1-alpha.3",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/GhentCDH/annotation-editor"
7
+ },
8
+ "type": "module",
9
+ "main": "./index.js",
10
+ "types": "./index.d.ts",
11
+ "dependencies": {
12
+ "@ghentcdh/annotated-text": "^1.0.9"
13
+ },
14
+ "peerDependencies": {
15
+ "vue": "^3.5.0",
16
+ "@ghentcdh/w3c-utils": "*",
17
+ "vue-router": "^5.0.0"
18
+ },
19
+ "peerDependenciesMeta": {
20
+ "vue-router": {
21
+ "optional": true
22
+ }
23
+ }
24
+ }