11/******/ (() => { // webpackBootstrap
22/******/ var __webpack_modules__ = ({
33
4+ /***/ "./js/HDSModel/HDSDatasourceDef.js"
5+ /*!*****************************************!*\
6+ !*** ./js/HDSModel/HDSDatasourceDef.js ***!
7+ \*****************************************/
8+ (__unused_webpack_module, exports, __webpack_require__) {
9+
10+ "use strict";
11+
12+ Object.defineProperty(exports, "__esModule", ({ value: true }));
13+ exports.HDSDatasourceDef = void 0;
14+ const localizeText_1 = __webpack_require__(/*! ../localizeText */ "./js/localizeText.js");
15+ class HDSDatasourceDef {
16+ #data;
17+ #key;
18+ #getAssets;
19+ constructor(key, definitionData, getAssets) {
20+ this.#key = key;
21+ this.#data = definitionData;
22+ this.#getAssets = getAssets;
23+ }
24+ get key() {
25+ return this.#key;
26+ }
27+ get data() {
28+ return this.#data;
29+ }
30+ /** label Localized */
31+ get label() {
32+ return (0, localizeText_1.localizeText)(this.#data.label);
33+ }
34+ /** description Localized */
35+ get description() {
36+ return (0, localizeText_1.localizeText)(this.#data.description);
37+ }
38+ /**
39+ * Resolved endpoint URL.
40+ * If the raw endpoint starts with `http`, it is used as-is.
41+ * Otherwise it is treated as `<assetKey>://<path>` and resolved
42+ * against the service-info assets map.
43+ * e.g. `datasets://medication` → `assets.datasets` + `medication`
44+ */
45+ get endpoint() {
46+ const raw = this.#data.endpoint;
47+ if (raw.startsWith('http'))
48+ return raw;
49+ const sep = raw.indexOf('://');
50+ if (sep === -1)
51+ return raw;
52+ const assetKey = raw.substring(0, sep);
53+ const path = raw.substring(sep + 3);
54+ const assets = this.#getAssets();
55+ const baseUrl = assets[assetKey];
56+ if (!baseUrl) {
57+ throw new Error(`Cannot resolve datasource endpoint "${raw}": no asset "${assetKey}" in service-info`);
58+ }
59+ // Ensure proper URL joining (handle trailing slash on baseUrl)
60+ return baseUrl.endsWith('/') ? baseUrl + path : baseUrl + '/' + path;
61+ }
62+ get queryParam() {
63+ return this.#data.queryParam;
64+ }
65+ get minQueryLength() {
66+ return this.#data.minQueryLength;
67+ }
68+ get resultKey() {
69+ return this.#data.resultKey;
70+ }
71+ get displayFields() {
72+ return this.#data.displayFields;
73+ }
74+ get valueFields() {
75+ return this.#data.valueFields;
76+ }
77+ }
78+ exports.HDSDatasourceDef = HDSDatasourceDef;
79+ //# sourceMappingURL=HDSDatasourceDef.js.map
80+
81+ /***/ },
82+
483/***/ "./js/HDSModel/HDSItemDef.js"
584/*!***********************************!*\
685 !*** ./js/HDSModel/HDSItemDef.js ***!
@@ -179,6 +258,59 @@ function mixAuthorizationLevels(level1, level2) {
179258
180259/***/ },
181260
261+ /***/ "./js/HDSModel/HDSModel-Datasources.js"
262+ /*!*********************************************!*\
263+ !*** ./js/HDSModel/HDSModel-Datasources.js ***!
264+ \*********************************************/
265+ (__unused_webpack_module, exports, __webpack_require__) {
266+
267+ "use strict";
268+
269+ Object.defineProperty(exports, "__esModule", ({ value: true }));
270+ exports.HDSModelDatasources = void 0;
271+ const HDSDatasourceDef_1 = __webpack_require__(/*! ./HDSDatasourceDef */ "./js/HDSModel/HDSDatasourceDef.js");
272+ /**
273+ * Datasources - Extension of HDSModel
274+ */
275+ class HDSModelDatasources {
276+ #model;
277+ #datasourceDefs;
278+ constructor(model) {
279+ this.#model = model;
280+ this.#datasourceDefs = {};
281+ }
282+ /**
283+ * get all datasource definitions
284+ */
285+ getAll() {
286+ const res = [];
287+ for (const key of Object.keys(this.#model.modelData.datasources || {})) {
288+ res.push(this.forKey(key));
289+ }
290+ return res;
291+ }
292+ /**
293+ * get datasource definition for a key
294+ */
295+ forKey(key, throwErrorIfNotFound = true) {
296+ if (this.#datasourceDefs[key])
297+ return this.#datasourceDefs[key];
298+ const datasources = this.#model.modelData.datasources || {};
299+ const defData = datasources[key];
300+ if (!defData) {
301+ if (throwErrorIfNotFound)
302+ throw new Error('Cannot find datasource definition with key: ' + key);
303+ return null;
304+ }
305+ this.#datasourceDefs[key] = new HDSDatasourceDef_1.HDSDatasourceDef(key, defData, () => this.#model.assets);
306+ return this.#datasourceDefs[key];
307+ }
308+ }
309+ exports.HDSModelDatasources = HDSModelDatasources;
310+ //# sourceMappingURL=HDSModel-Datasources.js.map
311+
312+ /***/ },
313+
182314/***/ "./js/HDSModel/HDSModel-EventTypes.js"
183315/*!********************************************!*\
184316 !*** ./js/HDSModel/HDSModel-EventTypes.js ***!
@@ -449,6 +581,7 @@ const HDSModel_Streams_1 = __webpack_require__(/*! ./HDSModel-Streams */ "./js/H
449581const HDSModel_Authorizations_1 = __webpack_require__(/*! ./HDSModel-Authorizations */ "./js/HDSModel/HDSModel-Authorizations.js");
450582const HDSModel_ItemsDefs_1 = __webpack_require__(/*! ./HDSModel-ItemsDefs */ "./js/HDSModel/HDSModel-ItemsDefs.js");
451583const HDSModel_EventTypes_1 = __webpack_require__(/*! ./HDSModel-EventTypes */ "./js/HDSModel/HDSModel-EventTypes.js");
584+ const HDSModel_Datasources_1 = __webpack_require__(/*! ./HDSModel-Datasources */ "./js/HDSModel/HDSModel-Datasources.js");
452585class HDSModel {
453586 /**
454587 * JSON definition file URL.
@@ -457,6 +590,8 @@ class HDSModel {
457590 #modelUrl;
458591 /** RAW content of model definitions */
459592 #modelData;
593+ /** Service-info assets map (e.g. { datasets: 'https://...', ... }) */
594+ #assets;
460595 /**
461596 * Map of properties loaded "on demand"
462597 */
@@ -468,6 +603,14 @@ class HDSModel {
468603 this.#modelUrl = modelUrl;
469604 this.laziliyLoadedMap = {};
470605 this.#modelData = null;
606+ this.#assets = {};
607+ }
608+ /** Service-info assets used for resolving datasource endpoints */
609+ get assets() {
610+ return this.#assets;
611+ }
612+ set assets(value) {
613+ this.#assets = value || {};
471614 }
472615 get isLoaded() {
473616 return !!this.#modelData;
@@ -528,6 +671,14 @@ class HDSModel {
528671 }
529672 return this.laziliyLoadedMap.eventTypes;
530673 }
674+ get datasources() {
675+ if (!this.isLoaded)
676+ throwNotLoadedError();
677+ if (!this.laziliyLoadedMap.datasources) {
678+ this.laziliyLoadedMap.datasources = new HDSModel_Datasources_1.HDSModelDatasources(this);
679+ }
680+ return this.laziliyLoadedMap.datasources;
681+ }
531682}
532683exports.HDSModel = HDSModel;
533684function throwNotLoadedError() {
@@ -574,6 +725,7 @@ async function initHDSModel() {
574725 if (!hdsModelInstance.isLoaded) {
575726 const service = new HDSService_1.HDSService();
576727 const serviceInfo = await service.info();
728+ hdsModelInstance.assets = serviceInfo.assets;
577729 await hdsModelInstance.load(serviceInfo.assets['hds-model']);
578730 }
579731 return hdsModelInstance;
@@ -14603,6 +14755,7 @@ describe('[HDLX] HDSLib.index', () => {
1460314755 \********************************/
1460414756(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
1460514757
14758+ /* provided dependency */ var process = __webpack_require__(/*! process/browser */ "./node_modules/process/browser.js");
1460614759const { assert } = __webpack_require__(/*! ./test-utils/deps-node */ "./tests/test-utils/deps-browser.js");
1460714760
1460814761const modelURL = 'https://model.datasafe.dev/pack.json';
@@ -14764,6 +14917,52 @@ describe('[MODX] Model', () => {
1476414917 });
1476514918 });
1476614919
14920+ // ---------- datasources ------------ //
14921+
14922+ describe('[MODSX] datasources', function () {
14923+ let dsModel;
14924+ const dsModelURL = process.env.MODEL_URL || modelURL;
14925+ before(async () => {
14926+ dsModel = new HDSModel(dsModelURL);
14927+ await dsModel.load();
14928+ });
14929+
14930+ it('[MODSA] get all datasources', async () => {
14931+ const datasources = dsModel.datasources.getAll();
14932+ assert.ok(datasources.length > 0);
14933+ for (const ds of datasources) {
14934+ assert.ok(ds.key);
14935+ assert.ok(ds.endpoint);
14936+ }
14937+ });
14938+
14939+ it('[MODSB] forKey returns medication datasource', async () => {
14940+ const ds = dsModel.datasources.forKey('medication');
14941+ assert.ok(ds);
14942+ assert.equal(ds.key, 'medication');
14943+ assert.equal(ds.endpoint, 'https://datasets.datasafe.dev/medication');
14944+ assert.equal(ds.queryParam, 'search');
14945+ assert.equal(ds.minQueryLength, 3);
14946+ assert.equal(ds.resultKey, 'medications');
14947+ assert.ok(ds.displayFields);
14948+ assert.ok(ds.valueFields);
14949+ });
14950+
14951+ it('[MODSC] forKey throws on unknown key', async () => {
14952+ try {
14953+ dsModel.datasources.forKey('dummy');
14954+ throw new Error('Should throw Error');
14955+ } catch (e) {
14956+ assert.equal(e.message, 'Cannot find datasource definition with key: dummy');
14957+ }
14958+ });
14959+
14960+ it('[MODSD] forKey returns null with throwErrorIfNotFound = false', async () => {
14961+ const notFound = dsModel.datasources.forKey('dummy', false);
14962+ assert.equal(notFound, null);
14963+ });
14964+ });
14965+
1476714966 // ---------- streams ------------ //
1476814967
1476914968 describe('[MOSX] streams', function () {
0 commit comments