@oml/language 0.19.1 → 0.19.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.
@@ -213,9 +213,9 @@ async function executeOperation(shared, context, operation, contexts) {
213
213
  return new Set([context.ontologyIri]);
214
214
  case 'createInstanceRef':
215
215
  ensureDescriptionOntology(context.ontology, operation.kind);
216
- await ensureReferenceImport(shared, context.ontology, operation.instanceIri);
216
+ await ensureReferenceImport(shared, context.ontology, operation.instanceIri, contexts);
217
217
  if (operation.typeIri) {
218
- await ensureReferenceImport(shared, context.ontology, operation.typeIri);
218
+ await ensureReferenceImport(shared, context.ontology, operation.typeIri, contexts);
219
219
  }
220
220
  {
221
221
  const ownedTypes = [];
@@ -241,9 +241,9 @@ async function executeOperation(shared, context, operation, contexts) {
241
241
  return new Set([context.ontologyIri]);
242
242
  case 'createRelationInstanceRef':
243
243
  ensureDescriptionOntology(context.ontology, operation.kind);
244
- await ensureReferenceImport(shared, context.ontology, operation.instanceIri);
244
+ await ensureReferenceImport(shared, context.ontology, operation.instanceIri, contexts);
245
245
  if (operation.typeIri) {
246
- await ensureReferenceImport(shared, context.ontology, operation.typeIri);
246
+ await ensureReferenceImport(shared, context.ontology, operation.typeIri, contexts);
247
247
  }
248
248
  {
249
249
  const ownedTypes = [];
@@ -271,12 +271,12 @@ async function executeOperation(shared, context, operation, contexts) {
271
271
  return new Set([context.ontologyIri]);
272
272
  case 'addAssertion':
273
273
  ensureDescriptionOntology(context.ontology, operation.kind);
274
- return await addAssertion(shared, context.ontology, operation.subjectIri, operation.predicateIri, operation.object)
274
+ return await addAssertion(shared, context.ontology, operation.subjectIri, operation.predicateIri, operation.object, contexts)
275
275
  ? new Set([context.ontologyIri])
276
276
  : new Set();
277
277
  case 'updateAssertion':
278
278
  ensureDescriptionOntology(context.ontology, operation.kind);
279
- return await updateAssertion(shared, context.ontology, operation.subjectIri, operation.predicateIri, operation.object)
279
+ return await updateAssertion(shared, context.ontology, operation.subjectIri, operation.predicateIri, operation.object, contexts)
280
280
  ? new Set([context.ontologyIri])
281
281
  : new Set();
282
282
  case 'removeAssertion':
@@ -285,11 +285,11 @@ async function executeOperation(shared, context, operation, contexts) {
285
285
  ? new Set([context.ontologyIri])
286
286
  : new Set();
287
287
  case 'addAnnotation':
288
- return await addAnnotation(shared, context.ontology, operation.subjectIri, operation.predicateIri, operation.object)
288
+ return await addAnnotation(shared, context.ontology, operation.subjectIri, operation.predicateIri, operation.object, contexts)
289
289
  ? new Set([context.ontologyIri])
290
290
  : new Set();
291
291
  case 'updateAnnotation':
292
- return await updateAnnotation(shared, context.ontology, operation.subjectIri, operation.predicateIri, operation.object)
292
+ return await updateAnnotation(shared, context.ontology, operation.subjectIri, operation.predicateIri, operation.object, contexts)
293
293
  ? new Set([context.ontologyIri])
294
294
  : new Set();
295
295
  case 'removeAnnotation':
@@ -343,7 +343,7 @@ function ensureUniqueLocalName(ontology, memberName) {
343
343
  throw new Error(`A member named '${memberName}' already exists in the ontology.`);
344
344
  }
345
345
  }
346
- async function addAssertion(shared, ontology, subjectIri, predicateIri, objectValue) {
346
+ async function addAssertion(shared, ontology, subjectIri, predicateIri, objectValue, contexts) {
347
347
  const normalizedPredicate = normalizeIri(predicateIri);
348
348
  const subject = findNamedInstanceByIri(ontology, subjectIri);
349
349
  if (!subject) {
@@ -354,7 +354,7 @@ async function addAssertion(shared, ontology, subjectIri, predicateIri, objectVa
354
354
  if ((subject.ownedTypes ?? []).some((entry) => matchesPredicateRef(ontology, entry?.type, normalizedTypeIri))) {
355
355
  return false;
356
356
  }
357
- await ensureReferenceImport(shared, ontology, normalizedTypeIri);
357
+ await ensureReferenceImport(shared, ontology, normalizedTypeIri, contexts);
358
358
  subject.ownedTypes ?? (subject.ownedTypes = []);
359
359
  pushAstArrayChild(subject, 'ownedTypes', {
360
360
  $type: 'TypeAssertion',
@@ -367,7 +367,7 @@ async function addAssertion(shared, ontology, subjectIri, predicateIri, objectVa
367
367
  throw new Error(`Predicate '${predicateIri}' applies only to relation instances.`);
368
368
  }
369
369
  const sourceIri = normalizeIri(asRequiredIri(objectValue, 'source assertion object'));
370
- await ensureReferenceImport(shared, ontology, sourceIri);
370
+ await ensureReferenceImport(shared, ontology, sourceIri, contexts);
371
371
  subject.sources ?? (subject.sources = []);
372
372
  subject.sources.push(asRef(ontology, sourceIri));
373
373
  return true;
@@ -377,7 +377,7 @@ async function addAssertion(shared, ontology, subjectIri, predicateIri, objectVa
377
377
  throw new Error(`Predicate '${predicateIri}' applies only to relation instances.`);
378
378
  }
379
379
  const targetIri = normalizeIri(asRequiredIri(objectValue, 'target assertion object'));
380
- await ensureReferenceImport(shared, ontology, targetIri);
380
+ await ensureReferenceImport(shared, ontology, targetIri, contexts);
381
381
  subject.targets ?? (subject.targets = []);
382
382
  subject.targets.push(asRef(ontology, targetIri));
383
383
  return true;
@@ -387,7 +387,7 @@ async function addAssertion(shared, ontology, subjectIri, predicateIri, objectVa
387
387
  .filter((assertion) => matchesPredicateRef(ontology, assertion?.property, normalizedPredicate));
388
388
  let propertyAssertion = matchingAssertions[0];
389
389
  if (!propertyAssertion) {
390
- await ensureReferenceImport(shared, ontology, normalizedPredicate);
390
+ await ensureReferenceImport(shared, ontology, normalizedPredicate, contexts);
391
391
  propertyAssertion = {
392
392
  $type: 'PropertyValueAssertion',
393
393
  property: asRef(ontology, normalizedPredicate),
@@ -401,10 +401,10 @@ async function addAssertion(shared, ontology, subjectIri, predicateIri, objectVa
401
401
  normalizePropertyAssertionGroup(subject, propertyAssertion, matchingAssertions.slice(1));
402
402
  }
403
403
  if (isIriLike(objectValue)) {
404
- await ensureReferenceImport(shared, ontology, normalizeIri(asRequiredIri(objectValue, 'assertion object')));
404
+ await ensureReferenceImport(shared, ontology, normalizeIri(asRequiredIri(objectValue, 'assertion object')), contexts);
405
405
  }
406
406
  else {
407
- await ensureTypedLiteralDatatypeImport(shared, ontology, objectValue);
407
+ await ensureTypedLiteralDatatypeImport(shared, ontology, objectValue, contexts);
408
408
  }
409
409
  appendAssertionValue(ontology, propertyAssertion, objectValue);
410
410
  normalizeAllPropertyAssertions(subject, ontology);
@@ -498,7 +498,7 @@ function removeAssertion(ontology, subjectIri, predicateIri, objectValue) {
498
498
  subject.ownedPropertyValues = remaining;
499
499
  return changed;
500
500
  }
501
- async function updateAssertion(shared, ontology, subjectIri, predicateIri, objectValue) {
501
+ async function updateAssertion(shared, ontology, subjectIri, predicateIri, objectValue, contexts) {
502
502
  const normalizedPredicate = normalizeIri(predicateIri);
503
503
  const subject = findNamedInstanceByIri(ontology, subjectIri);
504
504
  if (!subject) {
@@ -506,19 +506,19 @@ async function updateAssertion(shared, ontology, subjectIri, predicateIri, objec
506
506
  }
507
507
  if (normalizedPredicate === RDF_TYPE_IRI || isSourcePredicate(normalizedPredicate) || isTargetPredicate(normalizedPredicate)) {
508
508
  const removed = removeAssertion(ontology, subjectIri, predicateIri, undefined);
509
- const added = await addAssertion(shared, ontology, subjectIri, predicateIri, objectValue);
509
+ const added = await addAssertion(shared, ontology, subjectIri, predicateIri, objectValue, contexts);
510
510
  return removed || added;
511
511
  }
512
512
  subject.ownedPropertyValues ?? (subject.ownedPropertyValues = []);
513
513
  let propertyAssertion = subject.ownedPropertyValues.find((assertion) => matchesPredicateRef(ontology, assertion?.property, normalizedPredicate));
514
514
  if (!propertyAssertion) {
515
- return addAssertion(shared, ontology, subjectIri, predicateIri, objectValue);
515
+ return addAssertion(shared, ontology, subjectIri, predicateIri, objectValue, contexts);
516
516
  }
517
517
  if (isIriLike(objectValue)) {
518
- await ensureReferenceImport(shared, ontology, normalizeIri(asRequiredIri(objectValue, 'assertion object')));
518
+ await ensureReferenceImport(shared, ontology, normalizeIri(asRequiredIri(objectValue, 'assertion object')), contexts);
519
519
  }
520
520
  else {
521
- await ensureTypedLiteralDatatypeImport(shared, ontology, objectValue);
521
+ await ensureTypedLiteralDatatypeImport(shared, ontology, objectValue, contexts);
522
522
  }
523
523
  propertyAssertion.literalValues = [];
524
524
  propertyAssertion.referencedValues = [];
@@ -526,13 +526,13 @@ async function updateAssertion(shared, ontology, subjectIri, predicateIri, objec
526
526
  appendAssertionValue(ontology, propertyAssertion, objectValue);
527
527
  return true;
528
528
  }
529
- async function addAnnotation(shared, ontology, subjectIri, predicateIri, objectValue) {
529
+ async function addAnnotation(shared, ontology, subjectIri, predicateIri, objectValue, contexts) {
530
530
  const subject = findAnnotationSubjectByIri(ontology, subjectIri);
531
531
  if (!subject) {
532
532
  throw new Error(`Annotation subject '${subjectIri}' was not found in the ontology.`);
533
533
  }
534
534
  const normalizedPredicate = normalizeIri(predicateIri);
535
- await ensureReferenceImport(shared, ontology, normalizedPredicate);
535
+ await ensureReferenceImport(shared, ontology, normalizedPredicate, contexts);
536
536
  subject.ownedAnnotations ?? (subject.ownedAnnotations = []);
537
537
  const matchingAnnotations = subject.ownedAnnotations
538
538
  .filter((entry) => matchesPredicateRef(ontology, entry?.property, normalizedPredicate));
@@ -550,10 +550,10 @@ async function addAnnotation(shared, ontology, subjectIri, predicateIri, objectV
550
550
  normalizeAnnotationGroup(subject, annotation, matchingAnnotations.slice(1));
551
551
  }
552
552
  if (isIriLike(objectValue)) {
553
- await ensureReferenceImport(shared, ontology, normalizeIri(asRequiredIri(objectValue, 'annotation object')));
553
+ await ensureReferenceImport(shared, ontology, normalizeIri(asRequiredIri(objectValue, 'annotation object')), contexts);
554
554
  }
555
555
  else {
556
- await ensureTypedLiteralDatatypeImport(shared, ontology, objectValue);
556
+ await ensureTypedLiteralDatatypeImport(shared, ontology, objectValue, contexts);
557
557
  }
558
558
  appendAnnotationValue(ontology, annotation, objectValue);
559
559
  normalizeAllAnnotations(subject, ontology);
@@ -596,7 +596,7 @@ function removeAnnotation(ontology, subjectIri, predicateIri, objectValue) {
596
596
  subject.ownedAnnotations = kept;
597
597
  return changed;
598
598
  }
599
- async function updateAnnotation(shared, ontology, subjectIri, predicateIri, objectValue) {
599
+ async function updateAnnotation(shared, ontology, subjectIri, predicateIri, objectValue, contexts) {
600
600
  const subject = findAnnotationSubjectByIri(ontology, subjectIri);
601
601
  if (!subject) {
602
602
  throw new Error(`Annotation subject '${subjectIri}' was not found in the ontology.`);
@@ -605,13 +605,13 @@ async function updateAnnotation(shared, ontology, subjectIri, predicateIri, obje
605
605
  subject.ownedAnnotations ?? (subject.ownedAnnotations = []);
606
606
  const annotation = subject.ownedAnnotations.find((entry) => matchesPredicateRef(ontology, entry?.property, normalizedPredicate));
607
607
  if (!annotation) {
608
- return addAnnotation(shared, ontology, subjectIri, predicateIri, objectValue);
608
+ return addAnnotation(shared, ontology, subjectIri, predicateIri, objectValue, contexts);
609
609
  }
610
610
  if (isIriLike(objectValue)) {
611
- await ensureReferenceImport(shared, ontology, normalizeIri(asRequiredIri(objectValue, 'annotation object')));
611
+ await ensureReferenceImport(shared, ontology, normalizeIri(asRequiredIri(objectValue, 'annotation object')), contexts);
612
612
  }
613
613
  else {
614
- await ensureTypedLiteralDatatypeImport(shared, ontology, objectValue);
614
+ await ensureTypedLiteralDatatypeImport(shared, ontology, objectValue, contexts);
615
615
  }
616
616
  annotation.literalValues = [];
617
617
  annotation.referencedValues = [];
@@ -1033,7 +1033,7 @@ function toRefText(ontology, iri) {
1033
1033
  }
1034
1034
  return `<${normalizedIri}>`;
1035
1035
  }
1036
- async function ensureReferenceImport(shared, ontology, iri) {
1036
+ async function ensureReferenceImport(shared, ontology, iri, contexts) {
1037
1037
  const target = parseIriParts(iri);
1038
1038
  if (!target) {
1039
1039
  return;
@@ -1058,7 +1058,8 @@ async function ensureReferenceImport(shared, ontology, iri) {
1058
1058
  const importedNamespace = normalizeNamespace(String(resolveImportNamespaceRaw(imp) ?? ''));
1059
1059
  return importedNamespace === target.namespace;
1060
1060
  });
1061
- const importedOntology = await findOntologyByNamespace(shared, target.namespace);
1061
+ const importedOntology = findOntologyInContexts(contexts, target.namespace)
1062
+ ?? await findOntologyByNamespace(shared, target.namespace);
1062
1063
  const declaredPrefix = typeof importedOntology?.prefix === 'string' ? importedOntology.prefix.trim() : '';
1063
1064
  const preferredPrefix = declaredPrefix && !usedPrefixes.has(declaredPrefix)
1064
1065
  ? declaredPrefix
@@ -1199,6 +1200,12 @@ async function findOntologyByNamespace(shared, namespace) {
1199
1200
  const ontology = document?.parseResult?.value;
1200
1201
  return ontology && isOntology(ontology) ? ontology : undefined;
1201
1202
  }
1203
+ function findOntologyInContexts(contexts, namespace) {
1204
+ if (!contexts) {
1205
+ return undefined;
1206
+ }
1207
+ return contexts.get(normalizeOntologyIriKey(namespace))?.ontology;
1208
+ }
1202
1209
  function matchesRefTextTarget(ontology, statement, namespace, fragment) {
1203
1210
  const refText = getRefText(statement?.ref);
1204
1211
  if (!refText) {
@@ -1250,6 +1257,9 @@ function matchesRefTextFragment(statement, fragment) {
1250
1257
  return !!local && local === fragment;
1251
1258
  }
1252
1259
  function asLiteral(ontology, value) {
1260
+ if (isExplicitLiteralTransport(value)) {
1261
+ return explicitLiteralFromTransport(ontology, value);
1262
+ }
1253
1263
  if (isQuantityLiteralTransport(value)) {
1254
1264
  const raw = value.value;
1255
1265
  const num = typeof raw === 'number' ? raw : Number(raw);
@@ -1281,12 +1291,6 @@ function asLiteral(ontology, value) {
1281
1291
  }
1282
1292
  return literal;
1283
1293
  }
1284
- if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
1285
- const record = value;
1286
- if ((record.$type === 'DoubleLiteral' || record.$type === 'DecimalLiteral') && 'value' in record) {
1287
- return { $type: record.$type, value: record.value };
1288
- }
1289
- }
1290
1294
  if (typeof value === 'boolean') {
1291
1295
  return { $type: 'BooleanLiteral', value };
1292
1296
  }
@@ -1298,17 +1302,90 @@ function asLiteral(ontology, value) {
1298
1302
  }
1299
1303
  return { $type: 'QuotedLiteral', value: String(value ?? '') };
1300
1304
  }
1301
- async function ensureTypedLiteralDatatypeImport(shared, ontology, value) {
1305
+ function isExplicitLiteralTransport(value) {
1306
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
1307
+ return false;
1308
+ }
1309
+ const type = value.$type;
1310
+ return type === 'BooleanLiteral'
1311
+ || type === 'DecimalLiteral'
1312
+ || type === 'DoubleLiteral'
1313
+ || type === 'IntegerLiteral'
1314
+ || type === 'QuotedLiteral';
1315
+ }
1316
+ function explicitLiteralFromTransport(ontology, value) {
1317
+ if (value.$type === 'QuotedLiteral') {
1318
+ const literalValue = String(value.value ?? '');
1319
+ const langTag = literalLanguageTagFromTransport(value);
1320
+ const datatypeIri = literalDatatypeIriFromTransport(ontology, value);
1321
+ const literal = {
1322
+ $type: 'QuotedLiteral',
1323
+ value: literalValue,
1324
+ };
1325
+ if (langTag) {
1326
+ literal.langTag = langTag;
1327
+ }
1328
+ if (datatypeIri && !isXsdStringDatatypeIri(ontology, datatypeIri)) {
1329
+ literal.type = { $refText: toRefText(ontology, datatypeIri) };
1330
+ }
1331
+ return literal;
1332
+ }
1333
+ if (value.$type === 'BooleanLiteral') {
1334
+ return {
1335
+ $type: 'BooleanLiteral',
1336
+ value: booleanLiteralValue(value.value),
1337
+ };
1338
+ }
1339
+ const literal = {
1340
+ $type: value.$type,
1341
+ value: numericLiteralValue(value.$type, value.value),
1342
+ };
1343
+ const unitIri = literalUnitIriFromTransport(ontology, value);
1344
+ if (unitIri) {
1345
+ literal.unit = { $refText: toRefText(ontology, unitIri) };
1346
+ }
1347
+ return literal;
1348
+ }
1349
+ function numericLiteralValue(type, value) {
1350
+ const numberValue = typeof value === 'number'
1351
+ ? value
1352
+ : typeof value === 'string' && value.trim().length > 0
1353
+ ? Number(value.trim())
1354
+ : Number.NaN;
1355
+ if (!Number.isFinite(numberValue)) {
1356
+ throw new Error(`${type} value must be a finite number.`);
1357
+ }
1358
+ if (type === 'IntegerLiteral' && !Number.isInteger(numberValue)) {
1359
+ throw new Error('IntegerLiteral value must be an integer.');
1360
+ }
1361
+ return numberValue;
1362
+ }
1363
+ function booleanLiteralValue(value) {
1364
+ if (typeof value === 'boolean') {
1365
+ return value;
1366
+ }
1367
+ if (typeof value === 'string') {
1368
+ const normalized = value.trim().toLowerCase();
1369
+ if (normalized === 'true') {
1370
+ return true;
1371
+ }
1372
+ if (normalized === 'false') {
1373
+ return false;
1374
+ }
1375
+ }
1376
+ throw new Error('BooleanLiteral value must be true or false.');
1377
+ }
1378
+ async function ensureTypedLiteralDatatypeImport(shared, ontology, value, contexts) {
1302
1379
  if (isTypedQuotedLiteralTransport(value)) {
1303
1380
  const datatypeIri = literalDatatypeIriFromTransport(ontology, value);
1304
1381
  if (datatypeIri && !isXsdStringDatatypeIri(ontology, datatypeIri)) {
1305
- await ensureReferenceImport(shared, ontology, datatypeIri);
1382
+ await ensureReferenceImport(shared, ontology, datatypeIri, contexts);
1306
1383
  }
1307
1384
  }
1308
1385
  if (isQuantityLiteralTransport(value)) {
1309
1386
  const unitIri = literalUnitIriFromTransport(ontology, value);
1310
1387
  if (unitIri) {
1311
- await ensureReferenceImport(shared, ontology, unitIri);
1388
+ await ensureReferenceImport(shared, ontology, unitIri, contexts);
1312
1389
  }
1313
1390
  }
1314
1391
  }