@digicatapult/dtdl-parser 0.0.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/.depcheckrc +6 -0
- package/.github/CODEOWNERS +4 -0
- package/.github/workflows/release.yml +211 -0
- package/.github/workflows/test.yml +87 -0
- package/.prettierrc +9 -0
- package/.swcrc +32 -0
- package/LICENSE +201 -0
- package/README.md +1 -0
- package/dtdl/error/error.json +11 -0
- package/dtdl/simple/simple.json +9 -0
- package/eslint.config.mjs +52 -0
- package/interop/DTDLParserJSInterop.csproj +26 -0
- package/interop/DtdlErr.d.ts +26 -0
- package/interop/DtdlOm.d.ts +372 -0
- package/interop/LICENSE +21 -0
- package/interop/ModelParserInterop.cs +19 -0
- package/interop/README.md +1 -0
- package/interop/modelParser.js +11 -0
- package/interop/runtimeconfig.template.json +11 -0
- package/package.json +57 -0
- package/src/__tests__/fixtures/empty.json +1 -0
- package/src/__tests__/fixtures/nested/nested.json +1 -0
- package/src/__tests__/index.test.ts +119 -0
- package/src/error.ts +25 -0
- package/src/index.ts +130 -0
- package/src/interop.ts +9 -0
- package/test/mocharc.json +6 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type ModelingException = ParsingException | ResolutionException
|
|
2
|
+
|
|
3
|
+
export interface ParsingException {
|
|
4
|
+
ExceptionKind: 'Parsing'
|
|
5
|
+
Errors: ParsingError[]
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface ParsingError {
|
|
9
|
+
PrimaryID?: string
|
|
10
|
+
SecondaryID?: string
|
|
11
|
+
Property?: string
|
|
12
|
+
AuxProperty?: string
|
|
13
|
+
Type?: string
|
|
14
|
+
Value?: string
|
|
15
|
+
Restriction?: string
|
|
16
|
+
Transformation?: string
|
|
17
|
+
Violations?: string[]
|
|
18
|
+
Cause: string
|
|
19
|
+
Action: string
|
|
20
|
+
ValidationID: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ResolutionException {
|
|
24
|
+
ExceptionKind: 'Resolution'
|
|
25
|
+
UndefinedIdentifiers: string[]
|
|
26
|
+
}
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
export type DtdlObjectModel = { [entityId: string]: EntityType }
|
|
2
|
+
|
|
3
|
+
export interface ArrayInfo extends ComplexSchemaInfo {
|
|
4
|
+
EntityKind: 'Array'
|
|
5
|
+
elementSchema: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type ArrayType = ArrayInfo
|
|
9
|
+
|
|
10
|
+
export interface BooleanInfo extends PrimitiveSchemaInfo {
|
|
11
|
+
EntityKind: 'Boolean'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type BooleanType = BooleanInfo
|
|
15
|
+
|
|
16
|
+
export interface CommandInfo extends ContentInfo {
|
|
17
|
+
EntityKind: 'Command'
|
|
18
|
+
commandType?: string
|
|
19
|
+
request?: string
|
|
20
|
+
response?: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type CommandType = CommandInfo
|
|
24
|
+
|
|
25
|
+
export interface CommandPayloadInfo extends SchemaFieldInfo {
|
|
26
|
+
EntityKind: 'CommandPayload' | 'CommandRequest' | 'CommandResponse'
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type CommandPayloadType = CommandPayloadInfo | CommandRequestType | CommandResponseType
|
|
30
|
+
|
|
31
|
+
export interface CommandRequestInfo extends CommandPayloadInfo {
|
|
32
|
+
EntityKind: 'CommandRequest'
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type CommandRequestType = CommandRequestInfo
|
|
36
|
+
|
|
37
|
+
export interface CommandResponseInfo extends CommandPayloadInfo {
|
|
38
|
+
EntityKind: 'CommandResponse'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type CommandResponseType = CommandResponseInfo
|
|
42
|
+
|
|
43
|
+
export interface CommandTypeInfo extends EntityInfo {
|
|
44
|
+
EntityKind: 'CommandType'
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export type CommandTypeType = CommandTypeInfo
|
|
48
|
+
|
|
49
|
+
export interface ComplexSchemaInfo extends SchemaInfo {
|
|
50
|
+
EntityKind: 'Array' | 'Enum' | 'Map' | 'Object'
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export type ComplexSchemaType = ComplexSchemaInfo | ArrayType | EnumType | MapType | ObjectType
|
|
54
|
+
|
|
55
|
+
export interface ComponentInfo extends ContentInfo {
|
|
56
|
+
EntityKind: 'Component'
|
|
57
|
+
schema: string
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type ComponentType = ComponentInfo
|
|
61
|
+
|
|
62
|
+
export interface ContentInfo extends NamedEntityInfo {
|
|
63
|
+
EntityKind: 'Command' | 'Component' | 'Property' | 'Relationship' | 'Telemetry'
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export type ContentType = ContentInfo | CommandType | ComponentType | PropertyType | RelationshipType | TelemetryType
|
|
67
|
+
|
|
68
|
+
export interface DateInfo extends TemporalSchemaInfo {
|
|
69
|
+
EntityKind: 'Date'
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export type DateType = DateInfo
|
|
73
|
+
|
|
74
|
+
export interface DateTimeInfo extends TemporalSchemaInfo {
|
|
75
|
+
EntityKind: 'DateTime'
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export type DateTimeType = DateTimeInfo
|
|
79
|
+
|
|
80
|
+
export interface DoubleInfo extends NumericSchemaInfo {
|
|
81
|
+
EntityKind: 'Double'
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export type DoubleType = DoubleInfo
|
|
85
|
+
|
|
86
|
+
export interface DurationInfo extends TemporalSchemaInfo {
|
|
87
|
+
EntityKind: 'Duration'
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export type DurationType = DurationInfo
|
|
91
|
+
|
|
92
|
+
export interface EntityInfo {
|
|
93
|
+
EntityKind:
|
|
94
|
+
| 'Array'
|
|
95
|
+
| 'Boolean'
|
|
96
|
+
| 'Command'
|
|
97
|
+
| 'CommandPayload'
|
|
98
|
+
| 'CommandType'
|
|
99
|
+
| 'Component'
|
|
100
|
+
| 'Date'
|
|
101
|
+
| 'DateTime'
|
|
102
|
+
| 'Double'
|
|
103
|
+
| 'Duration'
|
|
104
|
+
| 'Enum'
|
|
105
|
+
| 'EnumValue'
|
|
106
|
+
| 'Field'
|
|
107
|
+
| 'Float'
|
|
108
|
+
| 'Integer'
|
|
109
|
+
| 'Interface'
|
|
110
|
+
| 'Long'
|
|
111
|
+
| 'Map'
|
|
112
|
+
| 'MapKey'
|
|
113
|
+
| 'MapValue'
|
|
114
|
+
| 'Object'
|
|
115
|
+
| 'Property'
|
|
116
|
+
| 'Relationship'
|
|
117
|
+
| 'String'
|
|
118
|
+
| 'Telemetry'
|
|
119
|
+
| 'Time'
|
|
120
|
+
| 'CommandRequest'
|
|
121
|
+
| 'CommandResponse'
|
|
122
|
+
| 'Unit'
|
|
123
|
+
| 'UnitAttribute'
|
|
124
|
+
| 'LatentType'
|
|
125
|
+
| 'NamedLatentType'
|
|
126
|
+
SupplementalTypes: string[]
|
|
127
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
128
|
+
SupplementalProperties: { [property: string]: any }
|
|
129
|
+
UndefinedTypes: string[]
|
|
130
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
131
|
+
UndefinedProperties: { [property: string]: any }
|
|
132
|
+
ClassId: string
|
|
133
|
+
comment?: string
|
|
134
|
+
description: { [languageCode: string]: string }
|
|
135
|
+
displayName: { [languageCode: string]: string }
|
|
136
|
+
languageMajorVersion: number
|
|
137
|
+
Id: string
|
|
138
|
+
ChildOf?: string
|
|
139
|
+
DefinedIn?: string
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export type EntityType =
|
|
143
|
+
| EntityInfo
|
|
144
|
+
| CommandTypeType
|
|
145
|
+
| InterfaceType
|
|
146
|
+
| LatentTypeType
|
|
147
|
+
| NamedEntityType
|
|
148
|
+
| SchemaType
|
|
149
|
+
| UnitType
|
|
150
|
+
|
|
151
|
+
export interface EnumInfo extends ComplexSchemaInfo {
|
|
152
|
+
EntityKind: 'Enum'
|
|
153
|
+
enumValues: string[]
|
|
154
|
+
valueSchema: string
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export type EnumType = EnumInfo
|
|
158
|
+
|
|
159
|
+
export interface EnumValueInfo extends NamedEntityInfo {
|
|
160
|
+
EntityKind: 'EnumValue'
|
|
161
|
+
enumValue: string | number | boolean
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export type EnumValueType = EnumValueInfo
|
|
165
|
+
|
|
166
|
+
export interface FieldInfo extends SchemaFieldInfo {
|
|
167
|
+
EntityKind: 'Field'
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export type FieldType = FieldInfo
|
|
171
|
+
|
|
172
|
+
export interface FloatInfo extends NumericSchemaInfo {
|
|
173
|
+
EntityKind: 'Float'
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export type FloatType = FloatInfo
|
|
177
|
+
|
|
178
|
+
export interface IntegerInfo extends NumericSchemaInfo {
|
|
179
|
+
EntityKind: 'Integer'
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export type IntegerType = IntegerInfo
|
|
183
|
+
|
|
184
|
+
export interface InterfaceInfo extends EntityInfo {
|
|
185
|
+
EntityKind: 'Interface'
|
|
186
|
+
contents: { [name: string]: string }
|
|
187
|
+
commands: { [name: string]: string }
|
|
188
|
+
components: { [name: string]: string }
|
|
189
|
+
properties: { [name: string]: string }
|
|
190
|
+
relationships: { [name: string]: string }
|
|
191
|
+
telemetries: { [name: string]: string }
|
|
192
|
+
extends: string[]
|
|
193
|
+
extendedBy: string[]
|
|
194
|
+
schemas: string[]
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export type InterfaceType = InterfaceInfo
|
|
198
|
+
|
|
199
|
+
export interface LatentTypeInfo extends EntityInfo {
|
|
200
|
+
EntityKind: 'LatentType'
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export type LatentTypeType = LatentTypeInfo
|
|
204
|
+
|
|
205
|
+
export interface LongInfo extends NumericSchemaInfo {
|
|
206
|
+
EntityKind: 'Long'
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export type LongType = LongInfo
|
|
210
|
+
|
|
211
|
+
export interface MapInfo extends ComplexSchemaInfo {
|
|
212
|
+
EntityKind: 'Map'
|
|
213
|
+
mapKey: string
|
|
214
|
+
mapValue: string
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export type MapType = MapInfo
|
|
218
|
+
|
|
219
|
+
export interface MapKeyInfo extends NamedEntityInfo {
|
|
220
|
+
EntityKind: 'MapKey'
|
|
221
|
+
schema: string
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export type MapKeyType = MapKeyInfo
|
|
225
|
+
|
|
226
|
+
export interface MapValueInfo extends SchemaFieldInfo {
|
|
227
|
+
EntityKind: 'MapValue'
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export type MapValueType = MapValueInfo
|
|
231
|
+
|
|
232
|
+
export interface NamedEntityInfo extends EntityInfo {
|
|
233
|
+
EntityKind:
|
|
234
|
+
| 'Command'
|
|
235
|
+
| 'CommandPayload'
|
|
236
|
+
| 'Component'
|
|
237
|
+
| 'EnumValue'
|
|
238
|
+
| 'Field'
|
|
239
|
+
| 'MapKey'
|
|
240
|
+
| 'MapValue'
|
|
241
|
+
| 'Property'
|
|
242
|
+
| 'Relationship'
|
|
243
|
+
| 'Telemetry'
|
|
244
|
+
| 'CommandRequest'
|
|
245
|
+
| 'CommandResponse'
|
|
246
|
+
| 'UnitAttribute'
|
|
247
|
+
| 'NamedLatentType'
|
|
248
|
+
name: string
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export type NamedEntityType =
|
|
252
|
+
| NamedEntityInfo
|
|
253
|
+
| ContentType
|
|
254
|
+
| EnumValueType
|
|
255
|
+
| MapKeyType
|
|
256
|
+
| NamedLatentTypeType
|
|
257
|
+
| SchemaFieldType
|
|
258
|
+
| UnitAttributeType
|
|
259
|
+
|
|
260
|
+
export interface NamedLatentTypeInfo extends NamedEntityInfo {
|
|
261
|
+
EntityKind: 'NamedLatentType'
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export type NamedLatentTypeType = NamedLatentTypeInfo
|
|
265
|
+
|
|
266
|
+
export interface NumericSchemaInfo extends PrimitiveSchemaInfo {
|
|
267
|
+
EntityKind: 'Double' | 'Float' | 'Integer' | 'Long'
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export type NumericSchemaType = NumericSchemaInfo | DoubleType | FloatType | IntegerType | LongType
|
|
271
|
+
|
|
272
|
+
export interface ObjectInfo extends ComplexSchemaInfo {
|
|
273
|
+
EntityKind: 'Object'
|
|
274
|
+
fields: string[]
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export type ObjectType = ObjectInfo
|
|
278
|
+
|
|
279
|
+
export interface PrimitiveSchemaInfo extends SchemaInfo {
|
|
280
|
+
EntityKind: 'Boolean' | 'Date' | 'DateTime' | 'Double' | 'Duration' | 'Float' | 'Integer' | 'Long' | 'String' | 'Time'
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export type PrimitiveSchemaType =
|
|
284
|
+
| PrimitiveSchemaInfo
|
|
285
|
+
| BooleanType
|
|
286
|
+
| NumericSchemaType
|
|
287
|
+
| StringType
|
|
288
|
+
| TemporalSchemaType
|
|
289
|
+
|
|
290
|
+
export interface PropertyInfo extends ContentInfo {
|
|
291
|
+
EntityKind: 'Property'
|
|
292
|
+
schema: string
|
|
293
|
+
writable: boolean
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export type PropertyType = PropertyInfo
|
|
297
|
+
|
|
298
|
+
export interface RelationshipInfo extends ContentInfo {
|
|
299
|
+
EntityKind: 'Relationship'
|
|
300
|
+
maxMultiplicity?: number
|
|
301
|
+
minMultiplicity?: number
|
|
302
|
+
properties: string[]
|
|
303
|
+
target?: string
|
|
304
|
+
writable: boolean
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export type RelationshipType = RelationshipInfo
|
|
308
|
+
|
|
309
|
+
export interface SchemaInfo extends EntityInfo {
|
|
310
|
+
EntityKind:
|
|
311
|
+
| 'Array'
|
|
312
|
+
| 'Boolean'
|
|
313
|
+
| 'Date'
|
|
314
|
+
| 'DateTime'
|
|
315
|
+
| 'Double'
|
|
316
|
+
| 'Duration'
|
|
317
|
+
| 'Enum'
|
|
318
|
+
| 'Float'
|
|
319
|
+
| 'Integer'
|
|
320
|
+
| 'Long'
|
|
321
|
+
| 'Map'
|
|
322
|
+
| 'Object'
|
|
323
|
+
| 'String'
|
|
324
|
+
| 'Time'
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
export type SchemaType = SchemaInfo | ComplexSchemaType | PrimitiveSchemaType
|
|
328
|
+
|
|
329
|
+
export interface SchemaFieldInfo extends NamedEntityInfo {
|
|
330
|
+
EntityKind: 'CommandPayload' | 'Field' | 'MapValue' | 'CommandRequest' | 'CommandResponse'
|
|
331
|
+
schema: string
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
export type SchemaFieldType = SchemaFieldInfo | CommandPayloadType | FieldType | MapValueType
|
|
335
|
+
|
|
336
|
+
export interface StringInfo extends PrimitiveSchemaInfo {
|
|
337
|
+
EntityKind: 'String'
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export type StringType = StringInfo
|
|
341
|
+
|
|
342
|
+
export interface TelemetryInfo extends ContentInfo {
|
|
343
|
+
EntityKind: 'Telemetry'
|
|
344
|
+
schema: string
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export type TelemetryType = TelemetryInfo
|
|
348
|
+
|
|
349
|
+
export interface TemporalSchemaInfo extends PrimitiveSchemaInfo {
|
|
350
|
+
EntityKind: 'Date' | 'DateTime' | 'Duration' | 'Time'
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export type TemporalSchemaType = TemporalSchemaInfo | DateType | DateTimeType | DurationType | TimeType
|
|
354
|
+
|
|
355
|
+
export interface TimeInfo extends TemporalSchemaInfo {
|
|
356
|
+
EntityKind: 'Time'
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export type TimeType = TimeInfo
|
|
360
|
+
|
|
361
|
+
export interface UnitInfo extends EntityInfo {
|
|
362
|
+
EntityKind: 'Unit'
|
|
363
|
+
symbol?: string
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export type UnitType = UnitInfo
|
|
367
|
+
|
|
368
|
+
export interface UnitAttributeInfo extends NamedEntityInfo {
|
|
369
|
+
EntityKind: 'UnitAttribute'
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
export type UnitAttributeType = UnitAttributeInfo
|
package/interop/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Digital Twin Consortium and contributors.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
using DTDLParser;
|
|
2
|
+
using System;
|
|
3
|
+
using System.Runtime.InteropServices.JavaScript;
|
|
4
|
+
using System.Runtime.Versioning;
|
|
5
|
+
|
|
6
|
+
namespace DtdlParserJSInterop;
|
|
7
|
+
|
|
8
|
+
[SupportedOSPlatform("browser")]
|
|
9
|
+
public partial class ModelParserInterop
|
|
10
|
+
{
|
|
11
|
+
public static void Main() => Console.WriteLine("dotnet loaded");
|
|
12
|
+
|
|
13
|
+
[JSExport]
|
|
14
|
+
public static string ParserVersion() => typeof(ModelParser).Assembly.FullName;
|
|
15
|
+
|
|
16
|
+
[JSExport]
|
|
17
|
+
public static string Parse(string dtdl) => new ModelParser().ParseToJson(dtdl);
|
|
18
|
+
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
This directory modifies code from `DTDLParser for .NET`, licensed under an [MIT License](./LICENSE). You can find the original project [here](https://github.com/digitaltwinconsortium/DTDLParser).
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { dotnet } from './_framework/dotnet.js'
|
|
2
|
+
|
|
3
|
+
const { getAssemblyExports, getConfig } = await dotnet.withDiagnosticTracing(false).create()
|
|
4
|
+
|
|
5
|
+
const config = getConfig()
|
|
6
|
+
const assemblyExports = await getAssemblyExports(config.mainAssemblyName)
|
|
7
|
+
|
|
8
|
+
const parserVersion = () => assemblyExports.DtdlParserJSInterop.ModelParserInterop.ParserVersion()
|
|
9
|
+
const parse = (dtdl) => assemblyExports.DtdlParserJSInterop.ModelParserInterop.Parse(dtdl)
|
|
10
|
+
|
|
11
|
+
export { parse, parserVersion }
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@digicatapult/dtdl-parser",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "JS tool to parse DTDL defined Ontologies",
|
|
5
|
+
"main": "src/index.ts",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"test": "NODE_ENV=test ./node_modules/.bin/mocha --config ./test/mocharc.json ./src/**/*.test.ts",
|
|
9
|
+
"build": "npx swc ./src ./package.json -d ./build --copy-files",
|
|
10
|
+
"clean": "rimraf -rf ./build",
|
|
11
|
+
"lint": "eslint .",
|
|
12
|
+
"depcheck": "depcheck"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/digicatapult/dtdl-parser.git"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"dtdl",
|
|
20
|
+
"digital",
|
|
21
|
+
"twins",
|
|
22
|
+
"parsing",
|
|
23
|
+
"tool"
|
|
24
|
+
],
|
|
25
|
+
"author": "Digital Catapult",
|
|
26
|
+
"license": "Apache-2.0",
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/digicatapult/dtdl-parser/issues"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://github.com/digicatapult/dtdl-parser#readme",
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@eslint/eslintrc": "^3.1.0",
|
|
33
|
+
"@eslint/js": "^9.12.0",
|
|
34
|
+
"@swc-node/register": "^1.10.9",
|
|
35
|
+
"@swc/cli": "^0.4.1-nightly.20240914",
|
|
36
|
+
"@swc/core": "^1.7.35",
|
|
37
|
+
"@types/chai": "^5.0.0",
|
|
38
|
+
"@types/mocha": "^10.0.9",
|
|
39
|
+
"@types/node": "^22.7.5",
|
|
40
|
+
"@typescript-eslint/eslint-plugin": "^8.8.1",
|
|
41
|
+
"@typescript-eslint/parser": "^8.8.1",
|
|
42
|
+
"chai": "^5.1.1",
|
|
43
|
+
"depcheck": "^1.4.7",
|
|
44
|
+
"eslint": "^9.12.0",
|
|
45
|
+
"eslint-config-prettier": "^9.1.0",
|
|
46
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
47
|
+
"globals": "^15.11.0",
|
|
48
|
+
"mocha": "^10.7.3",
|
|
49
|
+
"prettier": "^3.3.3",
|
|
50
|
+
"prettier-plugin-organize-imports": "^4.1.0",
|
|
51
|
+
"rimraf": "^6.0.1",
|
|
52
|
+
"typescript": "^5.6.3"
|
|
53
|
+
},
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">= 20"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { expect } from 'chai'
|
|
2
|
+
import { describe, it } from 'mocha'
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import { parseDirectories, searchForJsonFiles, validateDirectories } from '../index'
|
|
5
|
+
import { Parser } from '../interop'
|
|
6
|
+
|
|
7
|
+
const fixturesFilepath = path.resolve('src/__tests__/fixtures')
|
|
8
|
+
|
|
9
|
+
const exampleModel = {
|
|
10
|
+
'dtmi:com:example:base;1': {
|
|
11
|
+
languageMajorVersion: 3,
|
|
12
|
+
Id: 'dtmi:com:example:base;1',
|
|
13
|
+
ChildOf: 'dtmi:com:example;1',
|
|
14
|
+
DefinedIn: 'dtmi:com:example;1',
|
|
15
|
+
EntityKind: 'Interface',
|
|
16
|
+
ClassId: 'dtmi:dtdl:class:Interface;3',
|
|
17
|
+
extendedBy: ['dtmi:com:example;1'],
|
|
18
|
+
},
|
|
19
|
+
'dtmi:com:example;1': {
|
|
20
|
+
languageMajorVersion: 3,
|
|
21
|
+
Id: 'dtmi:com:example;1',
|
|
22
|
+
EntityKind: 'Interface',
|
|
23
|
+
ClassId: 'dtmi:dtdl:class:Interface;3',
|
|
24
|
+
extends: ['dtmi:com:example:base;1'],
|
|
25
|
+
},
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const mockParser: Parser = {
|
|
29
|
+
parse: () => JSON.stringify(exampleModel),
|
|
30
|
+
parserVersion: () => '1.0.0',
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const mockParserWithParsingException: Parser = {
|
|
34
|
+
parse: () => {
|
|
35
|
+
throw new Error(
|
|
36
|
+
JSON.stringify({
|
|
37
|
+
ExceptionKind: 'Parsing',
|
|
38
|
+
Errors: [{ Cause: '', Action: '', ValidationID: '' }],
|
|
39
|
+
})
|
|
40
|
+
)
|
|
41
|
+
},
|
|
42
|
+
parserVersion: () => '1.0.0',
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const mockParserWithResolutionException: Parser = {
|
|
46
|
+
parse: () => {
|
|
47
|
+
throw new Error(
|
|
48
|
+
JSON.stringify({
|
|
49
|
+
ExceptionKind: 'Resolution',
|
|
50
|
+
})
|
|
51
|
+
)
|
|
52
|
+
},
|
|
53
|
+
parserVersion: () => '1.0.0',
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
describe('parse', () => {
|
|
57
|
+
describe('search for files', () => {
|
|
58
|
+
it('should return nested json filepaths', async () => {
|
|
59
|
+
const filepaths = searchForJsonFiles(fixturesFilepath)
|
|
60
|
+
expect(filepaths.map((fp) => path.basename(fp))).to.deep.equal(['empty.json', 'nested.json'])
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
describe('valid parse', () => {
|
|
65
|
+
it('should return model', async () => {
|
|
66
|
+
const model = parseDirectories(fixturesFilepath, mockParser)
|
|
67
|
+
expect(model).to.deep.equal(exampleModel)
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
describe('invalid directory path', () => {
|
|
72
|
+
it('should return null', async () => {
|
|
73
|
+
const model = parseDirectories('invalid', mockParser)
|
|
74
|
+
expect(model).to.equal(null)
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
describe('parsing exception thrown by interop parser', () => {
|
|
79
|
+
it('should return null', async () => {
|
|
80
|
+
const model = parseDirectories(fixturesFilepath, mockParserWithParsingException)
|
|
81
|
+
expect(model).to.equal(null)
|
|
82
|
+
})
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
describe('parse', () => {
|
|
87
|
+
describe('valid validate', () => {
|
|
88
|
+
it('should returned validated true', async () => {
|
|
89
|
+
const isValid = validateDirectories(fixturesFilepath, mockParser, false)
|
|
90
|
+
expect(isValid).to.equal(true)
|
|
91
|
+
})
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
describe('invalid directory path', () => {
|
|
95
|
+
it('should return null', async () => {
|
|
96
|
+
const isValid = validateDirectories('invalid', mockParser, false)
|
|
97
|
+
expect(isValid).to.equal(false)
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
describe('parsing exception thrown by interop validate', () => {
|
|
102
|
+
it('should return false', async () => {
|
|
103
|
+
const isValid = validateDirectories(fixturesFilepath, mockParserWithParsingException, false)
|
|
104
|
+
expect(isValid).to.equal(false)
|
|
105
|
+
})
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
describe('resolution exception thrown by interop validate', () => {
|
|
109
|
+
it('should return false if including resolution check', async () => {
|
|
110
|
+
const isValid = validateDirectories(fixturesFilepath, mockParserWithResolutionException, true)
|
|
111
|
+
expect(isValid).to.equal(false)
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('should return true if NOT including resolution check', async () => {
|
|
115
|
+
const isValid = validateDirectories(fixturesFilepath, mockParserWithResolutionException, false)
|
|
116
|
+
expect(isValid).to.equal(true)
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
})
|
package/src/error.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ModelingException, ParsingException, ResolutionException } from '../interop/DtdlErr.js'
|
|
2
|
+
|
|
3
|
+
const { error } = console
|
|
4
|
+
|
|
5
|
+
const isParsingEx = (exception: ModelingException): exception is ParsingException => {
|
|
6
|
+
return exception.ExceptionKind === 'Parsing'
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const isResolutionEx = (exception: ModelingException): exception is ResolutionException => {
|
|
10
|
+
return exception.ExceptionKind === 'Resolution'
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const isResolutionException = (err: unknown) => {
|
|
14
|
+
if (!(err instanceof Error)) return false
|
|
15
|
+
return isResolutionEx(JSON.parse(err.message))
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const errorHandler = (err: unknown) => {
|
|
19
|
+
if (!(err instanceof Error)) return error(`Unexpected error: ${err}`)
|
|
20
|
+
|
|
21
|
+
const exception = JSON.parse(err.message) as ModelingException
|
|
22
|
+
|
|
23
|
+
if (!(isParsingEx(exception) || isResolutionEx(exception))) error('Unknown exception type')
|
|
24
|
+
error(exception)
|
|
25
|
+
}
|