@api-client/core 0.18.24 → 0.18.26

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 (59) hide show
  1. package/build/src/modeling/DomainEntity.d.ts +6 -1
  2. package/build/src/modeling/DomainEntity.d.ts.map +1 -1
  3. package/build/src/modeling/DomainEntity.js +24 -5
  4. package/build/src/modeling/DomainEntity.js.map +1 -1
  5. package/build/src/modeling/Semantics.d.ts +254 -0
  6. package/build/src/modeling/Semantics.d.ts.map +1 -1
  7. package/build/src/modeling/Semantics.js +328 -0
  8. package/build/src/modeling/Semantics.js.map +1 -1
  9. package/build/src/modeling/definitions/Email.js +1 -1
  10. package/build/src/modeling/definitions/Email.js.map +1 -1
  11. package/build/src/modeling/definitions/Password.d.ts.map +1 -1
  12. package/build/src/modeling/definitions/Password.js +1 -3
  13. package/build/src/modeling/definitions/Password.js.map +1 -1
  14. package/build/src/modeling/helpers/Intelisense.d.ts +7 -7
  15. package/build/src/modeling/helpers/Intelisense.d.ts.map +1 -1
  16. package/build/src/modeling/helpers/Intelisense.js +24 -58
  17. package/build/src/modeling/helpers/Intelisense.js.map +1 -1
  18. package/build/src/modeling/templates/meta/blog-publishing-platform.json +1 -1
  19. package/build/src/modeling/templates/meta/financial-services-platform.json +1 -1
  20. package/build/src/modeling/templates/meta/index.d.ts +1 -1
  21. package/build/src/modeling/templates/meta/index.js +1 -1
  22. package/build/src/modeling/templates/meta/index.js.map +1 -1
  23. package/build/src/modeling/templates/meta/iot-smart-home-platform.json +1 -1
  24. package/build/src/modeling/templates/verticals/business-services/financial-services-domain.d.ts.map +1 -1
  25. package/build/src/modeling/templates/verticals/business-services/financial-services-domain.js +248 -63
  26. package/build/src/modeling/templates/verticals/business-services/financial-services-domain.js.map +1 -1
  27. package/build/src/modeling/templates/verticals/technology-media/blog-domain.js +5 -5
  28. package/build/src/modeling/templates/verticals/technology-media/blog-domain.js.map +1 -1
  29. package/build/src/modeling/templates/verticals/technology-media/iot-smart-home-domain.d.ts.map +1 -1
  30. package/build/src/modeling/templates/verticals/technology-media/iot-smart-home-domain.js +2 -0
  31. package/build/src/modeling/templates/verticals/technology-media/iot-smart-home-domain.js.map +1 -1
  32. package/build/src/modeling/validation/postgresql.d.ts.map +1 -1
  33. package/build/src/modeling/validation/postgresql.js +0 -1
  34. package/build/src/modeling/validation/postgresql.js.map +1 -1
  35. package/build/src/runtime/modeling/Semantics.d.ts +84 -0
  36. package/build/src/runtime/modeling/Semantics.d.ts.map +1 -0
  37. package/build/src/runtime/modeling/Semantics.js +124 -0
  38. package/build/src/runtime/modeling/Semantics.js.map +1 -0
  39. package/build/tsconfig.tsbuildinfo +1 -1
  40. package/data/models/example-generator-api.json +8 -8
  41. package/package.json +1 -1
  42. package/src/modeling/DomainEntity.ts +27 -5
  43. package/src/modeling/Semantics.ts +493 -0
  44. package/src/modeling/definitions/Email.ts +1 -1
  45. package/src/modeling/definitions/Password.ts +1 -3
  46. package/src/modeling/helpers/Intelisense.ts +33 -65
  47. package/src/modeling/templates/meta/blog-publishing-platform.json +1 -1
  48. package/src/modeling/templates/meta/financial-services-platform.json +1 -1
  49. package/src/modeling/templates/meta/iot-smart-home-platform.json +1 -1
  50. package/src/modeling/templates/verticals/business-services/financial-services-domain.ts +285 -65
  51. package/src/modeling/templates/verticals/technology-media/blog-domain.ts +5 -5
  52. package/src/modeling/templates/verticals/technology-media/iot-smart-home-domain.ts +2 -0
  53. package/src/modeling/validation/postgresql.ts +0 -1
  54. package/src/runtime/modeling/Semantics.ts +196 -0
  55. package/tests/unit/modeling/client_ip_address_semantic.spec.ts +71 -0
  56. package/tests/unit/modeling/definitions/password.spec.ts +0 -2
  57. package/tests/unit/modeling/domain_entity_parents.spec.ts +243 -0
  58. package/tests/unit/modeling/semantic_runtime.spec.ts +113 -0
  59. package/tests/unit/modeling/semantics.spec.ts +68 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Semantics.js","sourceRoot":"","sources":["../../../../src/runtime/modeling/Semantics.ts"],"names":[],"mappings":"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","sourcesContent":["import { Jexl } from '@pawel-up/jexl/Jexl.js'\nimport type { DomainEntity } from '../../modeling/DomainEntity.js'\nimport {\n type AppliedDataSemantic,\n DataSemantics,\n type SemanticCondition,\n SemanticOperation,\n SemanticType,\n} from '../../modeling/Semantics.js'\nimport type { TransformFunction } from '@pawel-up/jexl'\n\n/**\n * Cache for JEXL instances to avoid recreation overhead\n */\nconst jexlCache = new Map<string, Jexl>()\n\n/**\n * Get or create a JEXL instance with optional custom transforms\n */\nexport function getJexlInstance(transforms?: Record<string, TransformFunction>): Jexl {\n const cacheKey = transforms ? JSON.stringify(Object.keys(transforms).sort()) : 'default'\n\n if (!jexlCache.has(cacheKey)) {\n const jexl = new Jexl()\n if (transforms) {\n Object.entries(transforms).forEach(([name, fn]) => {\n jexl.addTransform(name, fn)\n })\n }\n jexlCache.set(cacheKey, jexl)\n }\n\n return jexlCache.get(cacheKey) as Jexl\n}\n\n/**\n * Context object passed to semantic condition evaluation\n */\nexport interface SemanticExecutionContext {\n /**\n * The entity data being processed\n */\n entity: Record<string, unknown>\n /**\n * Current user context (if authenticated)\n */\n user?: {\n id?: string\n authenticated?: boolean\n roles?: string[]\n [key: string]: unknown\n }\n /**\n * The current database operation\n */\n operation: SemanticOperation\n /**\n * Applied semantics with their field mappings\n */\n appliedSemantics: AppliedDataSemantic[]\n /**\n * Configuration for the current semantic being evaluated\n */\n config?: Record<string, unknown>\n}\n\n/**\n * Builds a semantics object for JEXL evaluation that maps semantic types to actual field names.\n *\n * The resulting map should be used in JEXL expressions to reference semantic fields.\n *\n * @returns A map where keys are semantic type identifiers and values are the field names.\n *\n * @example\n * const semanticFieldMap = buildSemanticFieldMap(entity);\n * const result = await jexl.eval(\"semantics.CreatedTimestamp == null\", {\n * semantics: semanticFieldMap,\n * ...\n * }\n */\nexport function buildSemanticFieldMap(entity: DomainEntity): Record<string, string> {\n const semanticFieldMap: Record<string, string> = {}\n\n for (const property of entity.properties) {\n if (!property.info.name) {\n continue // Skip properties without a name\n }\n for (const semantic of property.semantics) {\n // We use the truncated `semantic.id` as the key, e.g. 'Password' so that it is possible to do something like:\n // `entity[semantics.Password] != null && !entity[semantics.Password].startsWith('$')`\n // Where the `semantics` object is the object returned by this function and\n // passed to the JEXL context.\n const semanticKey = semantic.id.replace('Semantic#', '')\n semanticFieldMap[semanticKey] = property.info.name\n }\n }\n return semanticFieldMap\n}\n\n/**\n * Evaluates a semantic condition against the execution context\n * In a real implementation, this would use JEXL to evaluate the expression\n *\n * @param condition The semantic condition to evaluate\n * @param context The execution context containing entity data, user info, etc.\n * @param semanticFieldMap A map of semantic field names to their actual field names.\n * Use the `buildSemanticFieldMap()` function to create this map.\n * @param jexl Optional JEXL instance to use for evaluation, defaults to a cached instance.\n * @returns A promise that resolves to true if the condition is met, false otherwise\n */\nexport function evaluateSemanticCondition(\n condition: SemanticCondition,\n context: SemanticExecutionContext,\n semanticFieldMap: Record<string, string>,\n jexl: Jexl = getJexlInstance()\n): Promise<boolean> {\n // Build the evaluation context\n const evalContext = {\n entity: context.entity,\n user: context.user,\n operation: context.operation,\n config: context.config,\n semantics: semanticFieldMap,\n }\n return jexl.eval(condition.expression, evalContext)\n}\n\n/**\n * Check if semantic should execute based on all its conditions\n *\n * @param semantic The semantic to check\n * @param context The execution context containing entity data, user info, etc.\n * @param semanticFieldMap A map of semantic field names to their actual field names.\n * Use the `buildSemanticFieldMap()` function to create this map.\n * @return A promise that resolves to true if all conditions are met, false otherwise\n */\nexport async function shouldSemanticExecute(\n semantic: AppliedDataSemantic,\n context: SemanticExecutionContext,\n semanticFieldMap: Record<string, string>\n): Promise<boolean> {\n const definition = DataSemantics[semantic.id]\n const conditions = definition?.runtime?.conditions\n\n if (!conditions || conditions.length === 0) {\n return true\n }\n\n const results = await Promise.all(\n conditions.map((condition) => evaluateSemanticCondition(condition, context, semanticFieldMap))\n )\n // All conditions must evaluate to true\n return results.every((result) => result === true)\n}\n\n/**\n * Helper to get the actual field name for a semantic type\n */\nexport function getFieldNameForSemantic(\n semanticType: SemanticType,\n semanticFieldMap: Record<string, string>\n): string | undefined {\n const semanticKey = semanticType.replace('Semantic#', '')\n return semanticFieldMap[semanticKey]\n}\n\n/**\n * Validates that all semantic references in conditions are available\n */\nexport function validateSemanticConditions(\n semantic: AppliedDataSemantic,\n semanticFieldMap: Record<string, string>\n): string[] {\n const definition = DataSemantics[semantic.id]\n const conditions = definition?.runtime?.conditions || []\n const errors: string[] = []\n\n conditions.forEach((condition, index) => {\n // Extract semantic references from the condition expression\n // Look for patterns like \"semantics.CreatedTimestamp\" or \"entity[semantics.Password]\"\n const semanticMatches = condition.expression.match(/semantics\\.(\\w+)/g)\n\n if (semanticMatches) {\n semanticMatches.forEach((match) => {\n const semanticKey = match.replace('semantics.', '')\n if (!semanticFieldMap[semanticKey]) {\n errors.push(\n `Condition ${index + 1} references semantic \"${semanticKey}\" but no field with that semantic was found`\n )\n }\n })\n }\n })\n\n return errors\n}\n"]}