@_linked/shape-ui 2.0.0 → 2.2.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 (210) hide show
  1. package/lib/esm/columns.d.ts +58 -0
  2. package/lib/esm/columns.js +173 -0
  3. package/lib/esm/columns.js.map +1 -0
  4. package/lib/esm/components/AddInstanceForms.d.ts +38 -0
  5. package/lib/esm/components/AddInstanceForms.js +143 -0
  6. package/lib/esm/components/AddInstanceForms.js.map +1 -0
  7. package/lib/esm/components/AddInstanceForms.module.css +12 -0
  8. package/lib/esm/components/BatchEditDrawer.d.ts +13 -0
  9. package/lib/esm/components/BatchEditDrawer.js +122 -0
  10. package/lib/esm/components/BatchEditDrawer.js.map +1 -0
  11. package/lib/esm/components/BatchEditDrawer.module.css +193 -0
  12. package/lib/esm/components/CustomMultiSelect.d.ts +26 -0
  13. package/lib/esm/components/CustomMultiSelect.js +344 -0
  14. package/lib/esm/components/CustomMultiSelect.js.map +1 -0
  15. package/lib/esm/components/CustomMultiSelect.module.css +291 -0
  16. package/lib/esm/components/DynamicFormField.d.ts +21 -0
  17. package/lib/esm/components/DynamicFormField.js +149 -0
  18. package/lib/esm/components/DynamicFormField.js.map +1 -0
  19. package/lib/esm/components/DynamicFormField.module.css +169 -0
  20. package/lib/esm/components/EditInstanceForms.d.ts +15 -0
  21. package/lib/esm/components/EditInstanceForms.js +118 -0
  22. package/lib/esm/components/EditInstanceForms.js.map +1 -0
  23. package/lib/esm/components/FilterBadge.d.ts +20 -0
  24. package/lib/esm/components/FilterBadge.js +26 -0
  25. package/lib/esm/components/FilterBadge.js.map +1 -0
  26. package/lib/esm/components/FilterBadge.module.css +25 -0
  27. package/lib/esm/components/FormField.d.ts +18 -0
  28. package/lib/esm/components/FormField.js +9 -0
  29. package/lib/esm/components/FormField.js.map +1 -0
  30. package/lib/esm/components/FormField.module.css +57 -0
  31. package/lib/esm/components/InstanceDeletionDialog.d.ts +17 -0
  32. package/lib/esm/components/InstanceDeletionDialog.js +83 -0
  33. package/lib/esm/components/InstanceDeletionDialog.js.map +1 -0
  34. package/lib/esm/components/InstanceDeletionDialog.module.css +59 -0
  35. package/lib/esm/components/InstanceOverview.d.ts +37 -0
  36. package/lib/esm/components/InstanceOverview.js +233 -0
  37. package/lib/esm/components/InstanceOverview.js.map +1 -0
  38. package/lib/esm/components/InstanceOverview.module.css +35 -0
  39. package/lib/esm/components/InstanceView.d.ts +29 -0
  40. package/lib/esm/components/InstanceView.js +97 -0
  41. package/lib/esm/components/InstanceView.js.map +1 -0
  42. package/lib/esm/components/InstanceView.module.css +157 -0
  43. package/lib/esm/components/NodeBadge.d.ts +25 -0
  44. package/lib/esm/components/NodeBadge.js +29 -0
  45. package/lib/esm/components/NodeBadge.js.map +1 -0
  46. package/lib/esm/components/NodeValuesEditor.d.ts +15 -0
  47. package/lib/esm/components/NodeValuesEditor.js +29 -0
  48. package/lib/esm/components/NodeValuesEditor.js.map +1 -0
  49. package/lib/esm/components/NodeValuesEditor.module.css +4 -0
  50. package/lib/esm/components/ReactTable.d.ts +50 -0
  51. package/lib/esm/components/ReactTable.js +370 -0
  52. package/lib/esm/components/ReactTable.js.map +1 -0
  53. package/lib/esm/components/ReactTable.module.css +950 -0
  54. package/lib/esm/components/TextfieldEditor.d.ts +1 -2
  55. package/lib/esm/components/TextfieldEditor.js +2 -2
  56. package/lib/esm/components/TextfieldEditor.js.map +1 -1
  57. package/lib/esm/components/forms.module.css +96 -0
  58. package/lib/esm/host.d.ts +196 -0
  59. package/lib/esm/host.js +25 -0
  60. package/lib/esm/host.js.map +1 -0
  61. package/lib/esm/hostContext.d.ts +34 -0
  62. package/lib/esm/hostContext.js +95 -0
  63. package/lib/esm/hostContext.js.map +1 -0
  64. package/lib/esm/index.d.ts +64 -10
  65. package/lib/esm/index.js +63 -14
  66. package/lib/esm/index.js.map +1 -1
  67. package/lib/esm/read.d.ts +48 -0
  68. package/lib/esm/read.js +96 -0
  69. package/lib/esm/read.js.map +1 -0
  70. package/lib/esm/search.d.ts +32 -0
  71. package/lib/esm/search.js +87 -0
  72. package/lib/esm/search.js.map +1 -0
  73. package/lib/esm/shape/contracts.d.ts +58 -0
  74. package/lib/esm/shape/contracts.js +15 -0
  75. package/lib/esm/shape/contracts.js.map +1 -0
  76. package/lib/esm/shape/naming.d.ts +30 -0
  77. package/lib/esm/shape/naming.js +52 -0
  78. package/lib/esm/shape/naming.js.map +1 -0
  79. package/lib/esm/shape/nodeDisplay.d.ts +36 -0
  80. package/lib/esm/shape/nodeDisplay.js +117 -0
  81. package/lib/esm/shape/nodeDisplay.js.map +1 -0
  82. package/lib/esm/shape/propertyTypes.d.ts +12 -0
  83. package/lib/esm/shape/propertyTypes.js +60 -0
  84. package/lib/esm/shape/propertyTypes.js.map +1 -0
  85. package/lib/esm/shape/propertyVisibility.d.ts +56 -0
  86. package/lib/esm/shape/propertyVisibility.js +112 -0
  87. package/lib/esm/shape/propertyVisibility.js.map +1 -0
  88. package/lib/esm/shape/shapeDependencies.d.ts +41 -0
  89. package/lib/esm/shape/shapeDependencies.js +141 -0
  90. package/lib/esm/shape/shapeDependencies.js.map +1 -0
  91. package/lib/esm/shape/tableFilters.d.ts +35 -0
  92. package/lib/esm/shape/tableFilters.js +171 -0
  93. package/lib/esm/shape/tableFilters.js.map +1 -0
  94. package/lib/esm/shape/useFormDependencies.d.ts +38 -0
  95. package/lib/esm/shape/useFormDependencies.js +178 -0
  96. package/lib/esm/shape/useFormDependencies.js.map +1 -0
  97. package/lib/esm/shape/validation.d.ts +15 -0
  98. package/lib/esm/shape/validation.js +106 -0
  99. package/lib/esm/shape/validation.js.map +1 -0
  100. package/lib/esm/tokens.css +25 -0
  101. package/lib/esm/types.d.ts +22 -0
  102. package/lib/esm/types.js +1 -0
  103. package/lib/esm/types.js.map +1 -0
  104. package/lib/esm/write.d.ts +51 -0
  105. package/lib/esm/write.js +99 -0
  106. package/lib/esm/write.js.map +1 -0
  107. package/package.json +44 -18
  108. package/src/backend.ts +1 -0
  109. package/src/columns.regression.test.ts +143 -0
  110. package/src/columns.test.ts +200 -0
  111. package/src/columns.ts +228 -0
  112. package/src/components/AddInstanceForms.module.css +12 -0
  113. package/src/components/AddInstanceForms.tsx +321 -0
  114. package/src/components/AvatarEditor.tsx +34 -0
  115. package/src/components/BatchEditDrawer.module.css +193 -0
  116. package/src/components/BatchEditDrawer.tsx +295 -0
  117. package/src/components/CheckboxEditor.module.css +6 -0
  118. package/src/components/CheckboxEditor.tsx +86 -0
  119. package/src/components/CustomMultiSelect.module.css +291 -0
  120. package/src/components/CustomMultiSelect.tsx +527 -0
  121. package/src/components/DateEditor.tsx +50 -0
  122. package/src/components/DynamicFormField.module.css +169 -0
  123. package/src/components/DynamicFormField.tsx +357 -0
  124. package/src/components/EditInstanceForms.tsx +260 -0
  125. package/src/components/FilterBadge.module.css +25 -0
  126. package/src/components/FilterBadge.tsx +70 -0
  127. package/src/components/FormField.module.css +57 -0
  128. package/src/components/FormField.tsx +59 -0
  129. package/src/components/ImageValueEditor.module.css +3 -0
  130. package/src/components/ImageValueEditor.tsx +82 -0
  131. package/src/components/InstanceDeletionDialog.module.css +59 -0
  132. package/src/components/InstanceDeletionDialog.tsx +175 -0
  133. package/src/components/InstanceOverview.module.css +35 -0
  134. package/src/components/InstanceOverview.tsx +374 -0
  135. package/src/components/InstanceView.module.css +157 -0
  136. package/src/components/InstanceView.tsx +212 -0
  137. package/src/components/NodeBadge.tsx +60 -0
  138. package/src/components/NodeValuesEditor.module.css +4 -0
  139. package/src/components/NodeValuesEditor.tsx +64 -0
  140. package/src/components/RadioButtonEditor.module.css +22 -0
  141. package/src/components/RadioButtonEditor.tsx +96 -0
  142. package/src/components/ReactTable.module.css +950 -0
  143. package/src/components/ReactTable.tsx +991 -0
  144. package/src/components/SelectEditor.tsx +85 -0
  145. package/src/components/ShapeTable.module.css +394 -0
  146. package/src/components/SwitchEditor.tsx +60 -0
  147. package/src/components/TextareaEditor.tsx +55 -0
  148. package/src/components/TextfieldEditor.tsx +67 -0
  149. package/src/components/ToggleEditor.tsx +63 -0
  150. package/src/components/forms.module.css +96 -0
  151. package/src/host.ts +226 -0
  152. package/src/hostContext.tsx +114 -0
  153. package/src/index.ts +99 -0
  154. package/src/package.ts +21 -0
  155. package/src/read.ts +148 -0
  156. package/src/search.test.ts +174 -0
  157. package/src/search.ts +108 -0
  158. package/src/shape/contracts.ts +66 -0
  159. package/src/shape/naming.ts +52 -0
  160. package/src/shape/nodeDisplay.ts +114 -0
  161. package/src/shape/propertyTypes.ts +86 -0
  162. package/src/shape/propertyVisibility.ts +180 -0
  163. package/src/shape/shapeDependencies.ts +183 -0
  164. package/src/shape/tableFilters.ts +223 -0
  165. package/src/shape/types.ts +1158 -0
  166. package/src/shape/useFormDependencies.ts +257 -0
  167. package/src/shape/validation.ts +121 -0
  168. package/src/tokens.css +25 -0
  169. package/src/types.ts +20 -0
  170. package/src/utils/helper.ts +35 -0
  171. package/src/write.test.ts +174 -0
  172. package/src/write.ts +114 -0
  173. package/.changeset/README.md +0 -20
  174. package/.changeset/config.json +0 -14
  175. package/.github/workflows/changeset-check.yml +0 -44
  176. package/.github/workflows/ci.yml +0 -43
  177. package/.github/workflows/publish.yml +0 -158
  178. package/CHANGELOG.md +0 -30
  179. package/lib/esm/components/AvatarEditor.d.ts +0 -20
  180. package/lib/esm/components/AvatarEditor.js +0 -7
  181. package/lib/esm/components/AvatarEditor.js.map +0 -1
  182. package/lib/esm/components/CheckboxEditor.d.ts +0 -21
  183. package/lib/esm/components/CheckboxEditor.js +0 -44
  184. package/lib/esm/components/CheckboxEditor.js.map +0 -1
  185. package/lib/esm/components/DateEditor.d.ts +0 -20
  186. package/lib/esm/components/DateEditor.js +0 -22
  187. package/lib/esm/components/DateEditor.js.map +0 -1
  188. package/lib/esm/components/RadioButtonEditor.d.ts +0 -23
  189. package/lib/esm/components/RadioButtonEditor.js +0 -41
  190. package/lib/esm/components/RadioButtonEditor.js.map +0 -1
  191. package/lib/esm/components/SelectEditor.d.ts +0 -21
  192. package/lib/esm/components/SelectEditor.js +0 -30
  193. package/lib/esm/components/SelectEditor.js.map +0 -1
  194. package/lib/esm/components/SwitchEditor.d.ts +0 -21
  195. package/lib/esm/components/SwitchEditor.js +0 -23
  196. package/lib/esm/components/SwitchEditor.js.map +0 -1
  197. package/lib/esm/components/TextareaEditor.d.ts +0 -23
  198. package/lib/esm/components/TextareaEditor.js +0 -15
  199. package/lib/esm/components/TextareaEditor.js.map +0 -1
  200. package/lib/esm/components/ToggleEditor.d.ts +0 -22
  201. package/lib/esm/components/ToggleEditor.js +0 -23
  202. package/lib/esm/components/ToggleEditor.js.map +0 -1
  203. package/lib/esm/ontologies/lincd-ui.d.ts +0 -6
  204. package/lib/esm/ontologies/lincd-ui.js +0 -18
  205. package/lib/esm/ontologies/lincd-ui.js.map +0 -1
  206. package/lib/esm/package.d.ts +0 -3
  207. package/lib/esm/package.js +0 -4
  208. package/lib/esm/package.js.map +0 -1
  209. package/tsconfig-cjs.json +0 -8
  210. package/tsconfig-esm.json +0 -9
@@ -0,0 +1,1158 @@
1
+ /**
2
+ * Shape Builder Types for Create Now
3
+ *
4
+ * Type definitions for SHACL shapes used in the Shape Builder.
5
+ * Shapes define validation constraints and form generation rules for ontology classes.
6
+ *
7
+ * Key concepts:
8
+ * - NodeShape: Top-level shape targeting a class (sh:targetClass)
9
+ * - PropertyShape: Constraints for a property path within a NodeShape
10
+ * - PropertyGroup: UI organization for form generation (sh:group)
11
+ * - PropertyPath: Simple or complex property paths (sh:path)
12
+ */
13
+
14
+ // ============================================================================
15
+ // Target Types
16
+ // ============================================================================
17
+
18
+ /**
19
+ * Target type for a NodeShape - determines what the shape validates
20
+ */
21
+ export type ShapeTargetType =
22
+ | 'targetClass' // sh:targetClass - instances of a class (most common)
23
+ | 'targetNode' // sh:targetNode - specific URIs
24
+ | 'targetSubjectsOf' // sh:targetSubjectsOf - subjects of property
25
+ | 'targetObjectsOf'; // sh:targetObjectsOf - objects of property
26
+
27
+ // ============================================================================
28
+ // Node Kind & Datatype Types
29
+ // ============================================================================
30
+
31
+ /**
32
+ * Node kind constraint (sh:nodeKind)
33
+ */
34
+ export type NodeKind =
35
+ | 'IRI' // sh:IRI - must be a URI
36
+ | 'Literal' // sh:Literal - must be a literal value
37
+ | 'BlankNode' // sh:BlankNode - must be a blank node
38
+ | 'BlankNodeOrIRI' // sh:BlankNodeOrIRI
39
+ | 'BlankNodeOrLiteral' // sh:BlankNodeOrLiteral
40
+ | 'IRIOrLiteral'; // sh:IRIOrLiteral
41
+
42
+ /**
43
+ * XSD datatypes for literal constraints (sh:datatype)
44
+ */
45
+ export type ShaclDatatype =
46
+ | 'xsd:string'
47
+ | 'xsd:integer'
48
+ | 'xsd:decimal'
49
+ | 'xsd:float'
50
+ | 'xsd:double'
51
+ | 'xsd:boolean'
52
+ | 'xsd:date'
53
+ | 'xsd:dateTime'
54
+ | 'xsd:time'
55
+ | 'xsd:anyURI'
56
+ | 'xsd:language'
57
+ | 'rdf:langString' // String with language tag
58
+ | 'rdf:HTML'; // HTML content
59
+
60
+ /**
61
+ * Mapping from user-friendly types to XSD datatypes
62
+ */
63
+ export const DATATYPE_MAP: Record<string, ShaclDatatype> = {
64
+ text: 'xsd:string',
65
+ string: 'xsd:string',
66
+ integer: 'xsd:integer',
67
+ number: 'xsd:decimal',
68
+ decimal: 'xsd:decimal',
69
+ float: 'xsd:float',
70
+ double: 'xsd:double',
71
+ boolean: 'xsd:boolean',
72
+ date: 'xsd:date',
73
+ datetime: 'xsd:dateTime',
74
+ time: 'xsd:time',
75
+ uri: 'xsd:anyURI',
76
+ url: 'xsd:anyURI',
77
+ language: 'xsd:language',
78
+ langString: 'rdf:langString',
79
+ html: 'rdf:HTML',
80
+ };
81
+
82
+ // ============================================================================
83
+ // Property Path Types
84
+ // ============================================================================
85
+
86
+ /**
87
+ * Property path types (SPARQL property paths)
88
+ */
89
+ export type PropertyPathType =
90
+ | 'predicate' // Simple: ex:name
91
+ | 'sequence' // A/B: ex:knows/ex:name
92
+ | 'alternative' // A|B: ex:father|ex:mother
93
+ | 'inverse' // ^A: ^ex:parent
94
+ | 'zeroOrMore' // A*: ex:knows*
95
+ | 'oneOrMore' // A+: ex:knows+
96
+ | 'zeroOrOne'; // A?: ex:middleName?
97
+
98
+ /**
99
+ * A segment in a property path
100
+ */
101
+ export interface PropertyPathSegment {
102
+ /** The type of this segment */
103
+ type: PropertyPathType;
104
+
105
+ /** For predicate: the property URI */
106
+ predicateUri?: string;
107
+
108
+ /** For predicate: human-readable name */
109
+ predicateName?: string;
110
+
111
+ /** For predicate: namespace prefix (e.g., "schema", "adms") */
112
+ predicatePrefix?: string;
113
+
114
+ /** For sequence/alternative: nested segments */
115
+ segments?: PropertyPathSegment[];
116
+
117
+ /** For inverse: the inverted path */
118
+ inversePath?: PropertyPathSegment;
119
+ }
120
+
121
+ /**
122
+ * Complete property path definition
123
+ */
124
+ export interface PropertyPath {
125
+ /** Unique ID for this path */
126
+ id: string;
127
+
128
+ /** Human-readable name (e.g., "Friend's Email") */
129
+ name: string;
130
+
131
+ /** The root segment of the path */
132
+ root: PropertyPathSegment;
133
+
134
+ /** Serialized SPARQL path (e.g., "ex:knows/ex:email") */
135
+ sparqlPath: string;
136
+
137
+ /** Serialized Turtle path for SHACL */
138
+ turtlePath: string;
139
+
140
+ /** The final property in the path (determines constraints) */
141
+ finalProperty: {
142
+ uri: string;
143
+ name: string;
144
+ propertyType: 'object' | 'datatype';
145
+ rangeClassUri?: string; // For object properties
146
+ rangeDatatype?: string; // For datatype properties
147
+ };
148
+ }
149
+
150
+ // ============================================================================
151
+ // Property Group Types
152
+ // ============================================================================
153
+
154
+ /**
155
+ * Property Group for organizing properties in forms (sh:PropertyGroup)
156
+ */
157
+ export interface BuilderPropertyGroup {
158
+ /** Unique ID */
159
+ id: string;
160
+
161
+ /** Group name (e.g., "Personal Information") */
162
+ name: string;
163
+
164
+ /** Optional description */
165
+ description?: string;
166
+
167
+ /** Display order (0-based) */
168
+ order: number;
169
+
170
+ /** Is this the default group? */
171
+ isDefault?: boolean;
172
+ }
173
+
174
+ // ============================================================================
175
+ // Constraint Types
176
+ // ============================================================================
177
+
178
+ /**
179
+ * Cardinality constraints (sh:minCount, sh:maxCount)
180
+ */
181
+ export interface CardinalityConstraint {
182
+ /** Minimum count (0 = optional) */
183
+ minCount?: number;
184
+
185
+ /** Maximum count (undefined = unlimited) */
186
+ maxCount?: number;
187
+ }
188
+
189
+ /**
190
+ * String-based constraints (for xsd:string, rdf:langString)
191
+ */
192
+ export interface StringConstraints {
193
+ /** Minimum string length (sh:minLength) */
194
+ minLength?: number;
195
+
196
+ /** Maximum string length (sh:maxLength) */
197
+ maxLength?: number;
198
+
199
+ /** Regex pattern the value must match (sh:pattern) */
200
+ pattern?: string;
201
+
202
+ /** Regex flags for pattern (sh:flags, e.g., "i" for case-insensitive) */
203
+ flags?: string;
204
+
205
+ /** Allowed languages (sh:languageIn, e.g., ['en', 'nl']) */
206
+ languageIn?: string[];
207
+
208
+ /** Each language can appear only once (sh:uniqueLang) */
209
+ uniqueLang?: boolean;
210
+ }
211
+
212
+ /**
213
+ * Numeric constraints (for xsd:integer, xsd:decimal, etc.)
214
+ */
215
+ export interface NumericConstraints {
216
+ /** Value must be > this (sh:minExclusive) */
217
+ minExclusive?: number;
218
+
219
+ /** Value must be >= this (sh:minInclusive) */
220
+ minInclusive?: number;
221
+
222
+ /** Value must be < this (sh:maxExclusive) */
223
+ maxExclusive?: number;
224
+
225
+ /** Value must be <= this (sh:maxInclusive) */
226
+ maxInclusive?: number;
227
+ }
228
+
229
+ /**
230
+ * A value that can be a node or literal with datatype/language
231
+ */
232
+ export interface PropertyValue {
233
+ /** The actual value (URI string or literal value) */
234
+ value: string;
235
+
236
+ /** Is this an IRI/URI reference? */
237
+ isUri?: boolean;
238
+
239
+ /** For literals: the XSD datatype */
240
+ datatype?: string;
241
+
242
+ /** For literals: the language tag */
243
+ language?: string;
244
+ }
245
+
246
+ /**
247
+ * Value constraints (sh:in, sh:hasValue, etc.)
248
+ */
249
+ export interface ValueConstraints {
250
+ /** Value must be one of these (sh:in) */
251
+ inValues?: PropertyValue[];
252
+
253
+ /** Must have exactly this value (sh:hasValue) */
254
+ hasValue?: PropertyValue;
255
+
256
+ /** Must equal value of another property (sh:equals) */
257
+ equals?: string; // Property path
258
+
259
+ /** Must not equal value of another property (sh:disjoint) */
260
+ disjoint?: string; // Property path
261
+
262
+ /** Must be less than value of another property (sh:lessThan) */
263
+ lessThan?: string; // Property path
264
+
265
+ /** Must be <= value of another property (sh:lessThanOrEquals) */
266
+ lessThanOrEquals?: string; // Property path
267
+ }
268
+
269
+ /**
270
+ * Qualified Value Shape constraint (sh:qualifiedValueShape)
271
+ * Allows: "At least N values must conform to shape X"
272
+ */
273
+ export interface QualifiedValueConstraint {
274
+ /** Reference to a shape that values must conform to */
275
+ qualifiedValueShape: string; // Shape URI
276
+
277
+ /** Minimum count of values that must conform (sh:qualifiedMinCount) */
278
+ qualifiedMinCount?: number;
279
+
280
+ /** Maximum count of values that may conform (sh:qualifiedMaxCount) */
281
+ qualifiedMaxCount?: number;
282
+
283
+ /** If true, sibling shapes are considered disjoint (sh:qualifiedValueShapesDisjoint) */
284
+ qualifiedValueShapesDisjoint?: boolean;
285
+ }
286
+
287
+ // ============================================================================
288
+ // Validation Types
289
+ // ============================================================================
290
+
291
+ /**
292
+ * Severity levels for validation results (sh:severity)
293
+ */
294
+ export type ShapeSeverity = 'Violation' | 'Warning' | 'Info';
295
+
296
+ /**
297
+ * Localized message for validation results (sh:message)
298
+ */
299
+ export interface LocalizedMessage {
300
+ /** The message text */
301
+ text: string;
302
+
303
+ /** Language tag (e.g., "en", "de", "nl") */
304
+ lang?: string;
305
+ }
306
+
307
+ // ============================================================================
308
+ // Property Shape Types
309
+ // ============================================================================
310
+
311
+ /**
312
+ * Constraints for object properties (owl:ObjectProperty)
313
+ */
314
+ export interface ObjectPropertyConstraints {
315
+ /** Required rdf:type of the value (sh:class) */
316
+ class?: string; // URI
317
+
318
+ /** Reference to a NodeShape for nested validation (sh:node) */
319
+ nodeShape?: string; // Shape URI
320
+ }
321
+
322
+ /**
323
+ * Constraints for datatype properties (owl:DatatypeProperty)
324
+ */
325
+ export interface DatatypePropertyConstraints {
326
+ /** Required XSD datatype (sh:datatype) */
327
+ datatype: ShaclDatatype;
328
+
329
+ /** String-specific constraints */
330
+ stringConstraints?: StringConstraints;
331
+
332
+ /** Numeric-specific constraints */
333
+ numericConstraints?: NumericConstraints;
334
+ }
335
+
336
+ /**
337
+ * PropertyShape - defines constraints for a single property path
338
+ */
339
+ export interface BuilderPropertyShape {
340
+ /** Unique ID */
341
+ id: string;
342
+
343
+ /** Human-readable name (required because path might be complex) */
344
+ name: string;
345
+
346
+ /** Description of what this property represents */
347
+ description?: string;
348
+
349
+ /** The property path this shape constrains */
350
+ path: PropertyPath;
351
+
352
+ /** Display order within group (sh:order) */
353
+ order: number;
354
+
355
+ /** Group this property belongs to (sh:group) */
356
+ groupId: string;
357
+
358
+ // === Type-specific constraints ===
359
+
360
+ /**
361
+ * For Object Properties (final property is owl:ObjectProperty):
362
+ * - sh:class - the rdf:type required for the value
363
+ * - OR sh:node - reference to another NodeShape
364
+ */
365
+ objectConstraints?: ObjectPropertyConstraints;
366
+
367
+ /**
368
+ * For Datatype Properties (final property is owl:DatatypeProperty):
369
+ */
370
+ datatypeConstraints?: DatatypePropertyConstraints;
371
+
372
+ /** Node kind constraint (sh:nodeKind, usually inferred from property type) */
373
+ nodeKind?: NodeKind;
374
+
375
+ /** Cardinality (sh:minCount, sh:maxCount) */
376
+ cardinality: CardinalityConstraint;
377
+
378
+ /** Value constraints (sh:in, sh:hasValue, sh:equals, etc.) */
379
+ valueConstraints?: ValueConstraints;
380
+
381
+ /** Qualified value shape constraint (sh:qualifiedValueShape) */
382
+ qualifiedValue?: QualifiedValueConstraint;
383
+
384
+ /** Is this property deactivated? (sh:deactivated) */
385
+ deactivated?: boolean;
386
+
387
+ /** Severity level for violations (sh:severity, default: Violation) */
388
+ severity?: ShapeSeverity;
389
+
390
+ /** Custom validation messages (sh:message) */
391
+ messages?: LocalizedMessage[];
392
+
393
+ /** Default value for form generation (sh:defaultValue) */
394
+ defaultValue?: PropertyValue;
395
+
396
+ /**
397
+ * Nested property shapes (sh:property on a PropertyShape)
398
+ * Used when the values of this property must have their own property constraints.
399
+ * E.g., an "address" property where the address value must have city, postalCode, etc.
400
+ * Note: This is different from sh:node which references an external shape.
401
+ */
402
+ nestedPropertyShapes?: BuilderPropertyShape[];
403
+
404
+ // === UI/Display Properties (Create Now extensions) ===
405
+
406
+ /** Is this a unique identifier property? */
407
+ isUniqueIdentifier?: boolean;
408
+
409
+ /** Is this the primary display property? */
410
+ isPrimaryDisplay?: boolean;
411
+
412
+ /** Display priority for compact views (lower = more important) */
413
+ displayPriority?: number;
414
+
415
+ /** Visual position in visual builder */
416
+ visualPosition?: { x: number; y: number };
417
+ }
418
+
419
+ // ============================================================================
420
+ // Logical Constraint Types
421
+ // ============================================================================
422
+
423
+ /**
424
+ * Boolean logic for combining property shapes
425
+ */
426
+ export interface LogicalConstraint {
427
+ /** Type of logical operation */
428
+ type: 'and' | 'or' | 'not' | 'xone';
429
+
430
+ /** Property shapes or nested shapes involved */
431
+ shapes: string[]; // PropertyShape IDs or NodeShape URIs
432
+ }
433
+
434
+ // ============================================================================
435
+ // Display Ordering Types
436
+ // ============================================================================
437
+
438
+ /**
439
+ * Display context types for property ordering
440
+ *
441
+ * - single: Show 1 most identifying property (e.g., name badge)
442
+ * - small: Show up to 3 key properties (e.g., compact list item)
443
+ * - card: Show up to 6 summary properties (e.g., card view)
444
+ * - table: Show properties suitable for table columns (unlimited)
445
+ */
446
+ export type DisplayContext = 'single' | 'small' | 'card' | 'table';
447
+
448
+ /**
449
+ * Property display order for a specific context
450
+ */
451
+ export interface PropertyDisplayOrder {
452
+ /** Property IDs in display order */
453
+ propertyIds: string[];
454
+ /** Whether this uses auto-generated defaults (false = user customized) */
455
+ isAutoGenerated: boolean;
456
+ }
457
+
458
+ /**
459
+ * Context-specific property orderings for a shape
460
+ *
461
+ * Each shape can have different property orders for different display contexts.
462
+ * If a context order is not specified or isAutoGenerated is true, the system
463
+ * will compute a sensible default based on property metadata.
464
+ *
465
+ * Auto-generation rules:
466
+ * - single: First required property, or first with highest importance
467
+ * - small: First 2-3 properties by required status, then importance
468
+ * - card: First 4-5 properties for summary display
469
+ * - form: All properties in their default order
470
+ * - table: All non-multiline properties suitable for columns
471
+ */
472
+ export interface ShapeDisplayOrderings {
473
+ /** Single property display (most identifying property) */
474
+ single?: PropertyDisplayOrder;
475
+ /** Small display (2-3 key properties) */
476
+ small?: PropertyDisplayOrder;
477
+ /** Card display (summary view, 4-5 properties) */
478
+ card?: PropertyDisplayOrder;
479
+ /** Form display (all editable properties) */
480
+ form?: PropertyDisplayOrder;
481
+ /** Table display (column order) */
482
+ table?: PropertyDisplayOrder;
483
+ }
484
+
485
+ // ============================================================================
486
+ // Node Shape Types
487
+ // ============================================================================
488
+
489
+ /**
490
+ * NodeShape - the top-level shape definition (sh:NodeShape)
491
+ */
492
+ export interface BuilderNodeShape {
493
+ /** Unique ID (local to builder) */
494
+ id: string;
495
+
496
+ /** Full URI of this shape */
497
+ uri: string;
498
+
499
+ /** Human-readable name (sh:name or rdfs:label) */
500
+ name: string;
501
+
502
+ /** Description (rdfs:comment or sh:description) */
503
+ description?: string;
504
+
505
+ // === Versioning ===
506
+
507
+ /** Current version string (e.g., "1.2.3" or "1.2.3-draft") */
508
+ version: string;
509
+
510
+ /** Version status */
511
+ versionStatus: 'draft' | 'published' | 'deprecated' | 'archived';
512
+
513
+ /** For deprecated versions: recommended replacement URI */
514
+ supersededBy?: string;
515
+
516
+ /** URI this was forked from (if any) */
517
+ forkedFrom?: string;
518
+
519
+ // === Targeting ===
520
+
521
+ /** How this shape targets nodes (sh:targetClass, sh:targetNode, etc.) */
522
+ targetType: ShapeTargetType;
523
+
524
+ /** For targetClass: the class URI from ontology (sh:targetClass) */
525
+ targetClass?: string;
526
+
527
+ /** For targetNode: specific URIs (sh:targetNode) */
528
+ targetNodes?: string[];
529
+
530
+ /** For targetSubjectsOf/targetObjectsOf: the property URI */
531
+ targetProperty?: string;
532
+
533
+ // === Structure ===
534
+
535
+ /** Property groups (ordered, for form organization) */
536
+ groups: BuilderPropertyGroup[];
537
+
538
+ /** Property shapes (ordered within groups) */
539
+ propertyShapes: BuilderPropertyShape[];
540
+
541
+ /** Logical constraints combining properties (sh:and, sh:or, sh:not, sh:xone) */
542
+ logicalConstraints?: LogicalConstraint[];
543
+
544
+ // === Validation Behavior ===
545
+
546
+ /** If true, only declared properties are allowed (sh:closed) */
547
+ closed?: boolean;
548
+
549
+ /** Properties to ignore when closed (sh:ignoredProperties) */
550
+ ignoredProperties?: string[];
551
+
552
+ /** Is this shape deactivated? (sh:deactivated) */
553
+ deactivated?: boolean;
554
+
555
+ // === Inheritance ===
556
+
557
+ /** Parent shape URIs this shape extends (conceptual, not SHACL standard) */
558
+ extendsShapes?: string[];
559
+
560
+ // === Metadata ===
561
+
562
+ /** Ontology this shape belongs to */
563
+ ontologyUri: string;
564
+
565
+ /** Ontology prefix for generated URIs */
566
+ ontologyPrefix?: string;
567
+
568
+ /** Package name for linked.cm URI generation (derived from project name) */
569
+ packageName?: string;
570
+
571
+ /** Owner project ID(s) */
572
+ ownerProjectIds?: string[];
573
+
574
+ /** Visibility (private/public) */
575
+ visibility?: 'local' | 'shared' | 'public';
576
+
577
+ /** License URI (required for public shapes) */
578
+ license?: string;
579
+
580
+ /** Created timestamp */
581
+ createdAt: string;
582
+
583
+ /** Updated timestamp */
584
+ updatedAt: string;
585
+
586
+ /** Visual position in visual builder */
587
+ visualPosition?: { x: number; y: number };
588
+
589
+ // === UI/Display Properties (Create Now extensions) ===
590
+
591
+ /** Icon identifier for the shape */
592
+ icon?: string;
593
+
594
+ /** Icon color (hex or named) */
595
+ iconColor?: string;
596
+
597
+ /** Feature tier (essential or complete) */
598
+ featureTier?: 'essential' | 'complete';
599
+
600
+ // === Discovery & Catalog ===
601
+
602
+ /** Search tags/keywords for catalog discovery */
603
+ tags?: string[];
604
+
605
+ /** Featured flag for highlighting in catalog */
606
+ featured?: boolean;
607
+
608
+ /** Category for catalog organization */
609
+ category?: string;
610
+
611
+ // === Display Orderings ===
612
+
613
+ /**
614
+ * Context-specific property orderings for different display scenarios.
615
+ * If not specified or isAutoGenerated is true, defaults are computed.
616
+ */
617
+ displayOrderings?: ShapeDisplayOrderings;
618
+ }
619
+
620
+ // ============================================================================
621
+ // Draft Types
622
+ // ============================================================================
623
+
624
+ /**
625
+ * Shape Builder Draft - complete builder state
626
+ * Mirrors OntologyDraft pattern from ontology builder
627
+ */
628
+ export interface ShapeBuilderDraft {
629
+ /** Unique draft ID */
630
+ id: string;
631
+
632
+ /** Associated ontology URI */
633
+ ontologyUri: string;
634
+
635
+ /** Associated ontology prefix */
636
+ ontologyPrefix: string;
637
+
638
+ /** All node shapes in this draft */
639
+ nodeShapes: BuilderNodeShape[];
640
+
641
+ /** Currently selected shape ID (for UI) */
642
+ selectedShapeId?: string;
643
+
644
+ /** Draft version for migrations */
645
+ version: number;
646
+
647
+ /** Timestamps */
648
+ createdAt: string;
649
+ updatedAt: string;
650
+ }
651
+
652
+ /** Current draft version for migrations */
653
+ export const CURRENT_SHAPE_DRAFT_VERSION = 1;
654
+
655
+ // ============================================================================
656
+ // Validation Result Types
657
+ // ============================================================================
658
+
659
+ export type ShapeValidationSeverity = 'error' | 'warning' | 'info';
660
+
661
+ export interface ShapeValidationIssue {
662
+ severity: ShapeValidationSeverity;
663
+ message: string;
664
+ element?: {
665
+ type: 'nodeShape' | 'propertyShape' | 'group';
666
+ id?: string;
667
+ name?: string;
668
+ };
669
+ field?: string;
670
+ rule: string;
671
+ suggestion?: string;
672
+ autoFixable?: boolean;
673
+ }
674
+
675
+ export interface ShapeValidationResult {
676
+ valid: boolean;
677
+ publishable: boolean;
678
+ errorCount: number;
679
+ warningCount: number;
680
+ issues: ShapeValidationIssue[];
681
+ validatedAt: string;
682
+ }
683
+
684
+ // ============================================================================
685
+ // Type Guards & Helpers
686
+ // ============================================================================
687
+
688
+ /**
689
+ * Check if a property shape targets an object property
690
+ */
691
+ export function isObjectPropertyShape(shape: BuilderPropertyShape): boolean {
692
+ return shape.path.finalProperty.propertyType === 'object';
693
+ }
694
+
695
+ /**
696
+ * Check if a property shape targets a datatype property
697
+ */
698
+ export function isDatatypePropertyShape(shape: BuilderPropertyShape): boolean {
699
+ return shape.path.finalProperty.propertyType === 'datatype';
700
+ }
701
+
702
+ /**
703
+ * Get the effective nodeKind for a property shape
704
+ */
705
+ export function getEffectiveNodeKind(shape: BuilderPropertyShape): NodeKind {
706
+ if (shape.nodeKind) return shape.nodeKind;
707
+ return isObjectPropertyShape(shape) ? 'IRI' : 'Literal';
708
+ }
709
+
710
+ /**
711
+ * Check if cardinality means "required"
712
+ */
713
+ export function isRequired(cardinality: CardinalityConstraint): boolean {
714
+ return (cardinality.minCount ?? 0) >= 1;
715
+ }
716
+
717
+ /**
718
+ * Check if cardinality means "single value"
719
+ */
720
+ export function isSingleValue(cardinality: CardinalityConstraint): boolean {
721
+ return cardinality.maxCount === 1;
722
+ }
723
+
724
+ /**
725
+ * Serialize a PropertyValue to Turtle syntax
726
+ */
727
+ export function serializePropertyValue(value: PropertyValue): string {
728
+ if (value.isUri) {
729
+ return `<${value.value}>`;
730
+ }
731
+ if (value.language) {
732
+ return `"${value.value}"@${value.language}`;
733
+ }
734
+ if (value.datatype) {
735
+ return `"${value.value}"^^${value.datatype}`;
736
+ }
737
+ return `"${value.value}"`;
738
+ }
739
+
740
+ /**
741
+ * Check if datatype is numeric
742
+ */
743
+ export function isNumericDatatype(datatype?: ShaclDatatype): boolean {
744
+ if (!datatype) return false;
745
+ return ['xsd:integer', 'xsd:decimal', 'xsd:float', 'xsd:double'].includes(
746
+ datatype
747
+ );
748
+ }
749
+
750
+ /**
751
+ * Check if datatype is string-based
752
+ */
753
+ export function isStringDatatype(datatype?: ShaclDatatype): boolean {
754
+ if (!datatype) return false;
755
+ return ['xsd:string', 'rdf:langString', 'rdf:HTML'].includes(datatype);
756
+ }
757
+
758
+ // ============================================================================
759
+ // Simple Builder Input Types (for easier hook/form usage)
760
+ // ============================================================================
761
+
762
+ /**
763
+ * Simple property path for builder inputs (just the predicate URI)
764
+ * Used for basic cases where we just need a single predicate
765
+ */
766
+ export interface SimplePropertyPath {
767
+ type: 'predicate';
768
+ predicate: string; // The property URI
769
+ predicateName?: string; // Display name
770
+ }
771
+
772
+ /**
773
+ * Simplified property shape for builder forms
774
+ * Flat structure that's easier to work with in forms/hooks
775
+ */
776
+ export interface SimplePropertyShape {
777
+ id: string;
778
+ uri?: string;
779
+ name: string;
780
+ description?: string;
781
+
782
+ /** Simple path (just the predicate URI) */
783
+ path?: SimplePropertyPath;
784
+
785
+ /** Display order */
786
+ order?: number;
787
+
788
+ /** Group ID */
789
+ groupId?: string;
790
+
791
+ // Cardinality (flat)
792
+ minCount?: number;
793
+ maxCount?: number;
794
+
795
+ // Value type
796
+ datatype?: string; // XSD datatype URI
797
+ classUri?: string; // For object properties
798
+ nodeKind?: NodeKind;
799
+
800
+ // String constraints (flat)
801
+ minLength?: number;
802
+ maxLength?: number;
803
+ pattern?: string;
804
+ flags?: string;
805
+
806
+ // Numeric constraints (flat)
807
+ minInclusive?: number;
808
+ maxInclusive?: number;
809
+ minExclusive?: number;
810
+ maxExclusive?: number;
811
+
812
+ // Display properties
813
+ displayPriority?: number;
814
+ isPrimaryDisplay?: boolean;
815
+ isUniqueIdentifier?: boolean;
816
+ }
817
+
818
+ /**
819
+ * Simplified node shape for builder forms
820
+ */
821
+ export interface SimpleNodeShape {
822
+ id: string;
823
+ uri?: string;
824
+ name: string;
825
+ description?: string;
826
+
827
+ version: string;
828
+ versionStatus: 'draft' | 'published' | 'deprecated';
829
+
830
+ targetType: ShapeTargetType;
831
+ targetClass?: string;
832
+
833
+ groups: BuilderPropertyGroup[];
834
+ propertyShapes: SimplePropertyShape[];
835
+
836
+ closed?: boolean;
837
+
838
+ ontologyUri: string;
839
+ ontologyPrefix?: string;
840
+ ownerProjectIds?: string[];
841
+ visibility?: 'local' | 'shared' | 'public';
842
+
843
+ icon?: string;
844
+ iconColor?: string;
845
+ visualPosition?: { x: number; y: number };
846
+
847
+ createdAt?: string;
848
+ updatedAt?: string;
849
+ featureTier?: 'essential' | 'complete';
850
+ }
851
+
852
+ /**
853
+ * Convert a SimplePropertyShape to a full BuilderPropertyShape
854
+ */
855
+ export function simpleToFullPropertyShape(simple: SimplePropertyShape): BuilderPropertyShape {
856
+ const path = simple.path
857
+ ? createSimplePath(simple.path.predicate, simple.path.predicateName)
858
+ : createSimplePath('http://example.org/unknownProperty', simple.name);
859
+
860
+ // Update final property type based on constraints
861
+ if (simple.classUri) {
862
+ path.finalProperty.propertyType = 'object';
863
+ path.finalProperty.rangeClassUri = simple.classUri;
864
+ } else if (simple.datatype) {
865
+ path.finalProperty.propertyType = 'datatype';
866
+ path.finalProperty.rangeDatatype = simple.datatype;
867
+ }
868
+
869
+ return {
870
+ id: simple.id,
871
+ name: simple.name,
872
+ description: simple.description,
873
+ path,
874
+ order: simple.order ?? 0,
875
+ groupId: simple.groupId || '',
876
+ nodeKind: simple.nodeKind,
877
+ cardinality: {
878
+ minCount: simple.minCount,
879
+ maxCount: simple.maxCount,
880
+ },
881
+ objectConstraints: simple.classUri ? { class: simple.classUri } : undefined,
882
+ datatypeConstraints: simple.datatype ? {
883
+ datatype: simple.datatype as ShaclDatatype,
884
+ stringConstraints: (simple.minLength !== undefined || simple.maxLength !== undefined || simple.pattern) ? {
885
+ minLength: simple.minLength,
886
+ maxLength: simple.maxLength,
887
+ pattern: simple.pattern,
888
+ flags: simple.flags,
889
+ } : undefined,
890
+ numericConstraints: (simple.minInclusive !== undefined || simple.maxInclusive !== undefined ||
891
+ simple.minExclusive !== undefined || simple.maxExclusive !== undefined) ? {
892
+ minInclusive: simple.minInclusive,
893
+ maxInclusive: simple.maxInclusive,
894
+ minExclusive: simple.minExclusive,
895
+ maxExclusive: simple.maxExclusive,
896
+ } : undefined,
897
+ } : undefined,
898
+ displayPriority: simple.displayPriority,
899
+ isPrimaryDisplay: simple.isPrimaryDisplay,
900
+ isUniqueIdentifier: simple.isUniqueIdentifier,
901
+ };
902
+ }
903
+
904
+ /**
905
+ * Convert a full BuilderPropertyShape to a SimplePropertyShape
906
+ */
907
+ export function fullToSimplePropertyShape(full: BuilderPropertyShape): SimplePropertyShape {
908
+ return {
909
+ id: full.id,
910
+ name: full.name,
911
+ description: full.description,
912
+ path: full.path ? {
913
+ type: 'predicate',
914
+ predicate: full.path.root.predicateUri || full.path.sparqlPath,
915
+ predicateName: full.path.root.predicateName,
916
+ } : undefined,
917
+ order: full.order,
918
+ groupId: full.groupId,
919
+ minCount: full.cardinality?.minCount,
920
+ maxCount: full.cardinality?.maxCount,
921
+ datatype: full.datatypeConstraints?.datatype,
922
+ classUri: full.objectConstraints?.class,
923
+ nodeKind: full.nodeKind,
924
+ minLength: full.datatypeConstraints?.stringConstraints?.minLength,
925
+ maxLength: full.datatypeConstraints?.stringConstraints?.maxLength,
926
+ pattern: full.datatypeConstraints?.stringConstraints?.pattern,
927
+ flags: full.datatypeConstraints?.stringConstraints?.flags,
928
+ minInclusive: full.datatypeConstraints?.numericConstraints?.minInclusive,
929
+ maxInclusive: full.datatypeConstraints?.numericConstraints?.maxInclusive,
930
+ minExclusive: full.datatypeConstraints?.numericConstraints?.minExclusive,
931
+ maxExclusive: full.datatypeConstraints?.numericConstraints?.maxExclusive,
932
+ displayPriority: full.displayPriority,
933
+ isPrimaryDisplay: full.isPrimaryDisplay,
934
+ isUniqueIdentifier: full.isUniqueIdentifier,
935
+ };
936
+ }
937
+
938
+ /**
939
+ * Generate a simple predicate path from a property URI
940
+ */
941
+ export function createSimplePath(
942
+ propertyUri: string,
943
+ propertyName?: string,
944
+ propertyType: 'object' | 'datatype' = 'datatype',
945
+ rangeClassUri?: string,
946
+ rangeDatatype?: string
947
+ ): PropertyPath {
948
+ const name = propertyName || propertyUri.split(/[#/]/).pop() || propertyUri;
949
+ return {
950
+ id: crypto.randomUUID(),
951
+ name,
952
+ root: {
953
+ type: 'predicate',
954
+ predicateUri: propertyUri,
955
+ predicateName: name,
956
+ },
957
+ sparqlPath: propertyUri,
958
+ turtlePath: `<${propertyUri}>`,
959
+ finalProperty: {
960
+ uri: propertyUri,
961
+ name,
962
+ propertyType,
963
+ rangeClassUri,
964
+ rangeDatatype,
965
+ },
966
+ };
967
+ }
968
+
969
+ // ============================================================================
970
+ // Shape Registry Types (for Catalog)
971
+ // ============================================================================
972
+
973
+ /**
974
+ * Shape status in the registry
975
+ */
976
+ export type ShapeStatus = 'active' | 'deprecated' | 'draft' | 'archived';
977
+
978
+ /**
979
+ * Verification level for shapes
980
+ */
981
+ export type ShapeVerificationLevel = 'verified' | 'community' | 'unverified';
982
+
983
+ /**
984
+ * Shape visibility (openness level)
985
+ * - 'local': Level 1 — lives in app's repo
986
+ * - 'shared': Level 2 — optionally published to npm
987
+ * - 'public': Level 3 — source in Linked org public repo
988
+ */
989
+ export type ShapeVisibility = 'local' | 'shared' | 'public';
990
+
991
+ /**
992
+ * Shape version information
993
+ *
994
+ * URI Strategy:
995
+ * - Base URI: /shapes/{shapeName}Shape (holds metadata + latest release copy)
996
+ * - Version URI: /shapes/{shapeName}Shape/{version} (e.g., /shapes/PersonShape/1.0.0)
997
+ *
998
+ * The base shape always contains:
999
+ * - Metadata (name, description, owner, etc.)
1000
+ * - A copy of the latest published version's constraints
1001
+ * - Reference to all versions via cnSh:hasVersion
1002
+ */
1003
+ export interface ShapeVersion {
1004
+ /** SemVer version string (e.g., "1.0.0", "1.2.3-beta") */
1005
+ version: string;
1006
+
1007
+ /** Full URI for this version */
1008
+ versionUri: string;
1009
+
1010
+ /** Status of this version */
1011
+ status: 'draft' | 'published' | 'deprecated' | 'archived';
1012
+
1013
+ /** Release notes for this version */
1014
+ releaseNotes?: string;
1015
+
1016
+ /** When this version was published */
1017
+ publishedAt?: string;
1018
+
1019
+ /** Who published this version */
1020
+ publishedBy?: string;
1021
+
1022
+ /** Is this the latest stable release? */
1023
+ isLatest?: boolean;
1024
+ }
1025
+
1026
+ /**
1027
+ * Shape registry entry for catalog display
1028
+ *
1029
+ * Represents a shape in the catalog with metadata for discovery.
1030
+ * The base URI always holds the latest version's data.
1031
+ */
1032
+ export interface ShapeRegistryEntry {
1033
+ /** Base URI for the shape (without version) */
1034
+ uri: string;
1035
+
1036
+ /** Human-readable name */
1037
+ name: string;
1038
+
1039
+ /** Description of what this shape validates */
1040
+ description?: string;
1041
+
1042
+ /** Target class this shape validates (sh:targetClass) */
1043
+ targetClass?: string;
1044
+
1045
+ /** Prefix of the target ontology */
1046
+ ontologyPrefix?: string;
1047
+
1048
+ /** URI of the source ontology */
1049
+ ontologyUri?: string;
1050
+
1051
+ /** Keywords/tags for discovery */
1052
+ keywords: string[];
1053
+
1054
+ /** Domain categories */
1055
+ domain: string[];
1056
+
1057
+ /** Current version (latest published, or draft if none published) */
1058
+ version: string;
1059
+
1060
+ /** All available versions */
1061
+ versions?: ShapeVersion[];
1062
+
1063
+ /** Maintainer information */
1064
+ maintainer: {
1065
+ name: string;
1066
+ type: 'organization' | 'community' | 'individual' | 'local';
1067
+ url?: string;
1068
+ };
1069
+
1070
+ /** Current status */
1071
+ status: ShapeStatus;
1072
+
1073
+ /** Last updated timestamp */
1074
+ lastUpdated: string;
1075
+
1076
+ /** Created timestamp */
1077
+ createdAt?: string;
1078
+
1079
+ /** Verification info */
1080
+ verification: {
1081
+ level: ShapeVerificationLevel;
1082
+ verifiedBy?: string[];
1083
+ };
1084
+
1085
+ /** Owner project IDs (who can edit) */
1086
+ ownerProjectIds?: string[];
1087
+
1088
+ /** Whether this shape is in use in current project */
1089
+ inUse?: boolean;
1090
+
1091
+ /** Whether this is a local/project shape */
1092
+ isLocal?: boolean;
1093
+
1094
+ /** Whether this shape is owned by current project */
1095
+ isOwned?: boolean;
1096
+
1097
+ /** Icon name for UI */
1098
+ icon?: string;
1099
+
1100
+ /** Icon color for UI */
1101
+ iconColor?: string;
1102
+
1103
+ /** Visibility setting */
1104
+ visibility?: ShapeVisibility;
1105
+
1106
+ /** License (required for public shapes) */
1107
+ license?: string;
1108
+
1109
+ /** Whether this shape is featured in catalog */
1110
+ featured?: boolean;
1111
+
1112
+ /** Tags for filtering */
1113
+ tags?: string[];
1114
+
1115
+ /** Stats for discovery */
1116
+ stats: {
1117
+ /** Number of property shapes defined */
1118
+ propertyCount: number;
1119
+
1120
+ /** Number of projects using this shape */
1121
+ usageCount: number;
1122
+
1123
+ /** User rating (0-5) */
1124
+ rating?: number;
1125
+
1126
+ /** Number of downloads/imports */
1127
+ downloadCount?: number;
1128
+
1129
+ /** Number of forks */
1130
+ forkCount?: number;
1131
+ };
1132
+ }
1133
+
1134
+ /**
1135
+ * Filter state for shape catalog
1136
+ */
1137
+ export interface ShapeFilterState {
1138
+ /** Filter by domain/category */
1139
+ domains: string[];
1140
+
1141
+ /** Filter by status */
1142
+ status: string[];
1143
+
1144
+ /** Filter by ontology */
1145
+ ontology: string[];
1146
+
1147
+ /** Filter by visibility */
1148
+ visibility: string[];
1149
+
1150
+ /** Search query */
1151
+ searchQuery?: string;
1152
+
1153
+ /** Only show featured shapes */
1154
+ featuredOnly?: boolean;
1155
+
1156
+ /** Only show shapes owned by current project */
1157
+ ownedOnly?: boolean;
1158
+ }