@cepseudo/ngsi-ld 1.0.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.
- package/README.md +425 -0
- package/dist/cache/entity_cache.d.ts +42 -0
- package/dist/cache/entity_cache.d.ts.map +1 -0
- package/dist/cache/entity_cache.js +93 -0
- package/dist/cache/entity_cache.js.map +1 -0
- package/dist/components/ngsi_ld_collector.d.ts +25 -0
- package/dist/components/ngsi_ld_collector.d.ts.map +1 -0
- package/dist/components/ngsi_ld_collector.js +13 -0
- package/dist/components/ngsi_ld_collector.js.map +1 -0
- package/dist/components/ngsi_ld_harvester.d.ts +25 -0
- package/dist/components/ngsi_ld_harvester.d.ts.map +1 -0
- package/dist/components/ngsi_ld_harvester.js +13 -0
- package/dist/components/ngsi_ld_harvester.js.map +1 -0
- package/dist/components/type_guards.d.ts +15 -0
- package/dist/components/type_guards.d.ts.map +1 -0
- package/dist/components/type_guards.js +25 -0
- package/dist/components/type_guards.js.map +1 -0
- package/dist/endpoints/attrs.d.ts +7 -0
- package/dist/endpoints/attrs.d.ts.map +1 -0
- package/dist/endpoints/attrs.js +37 -0
- package/dist/endpoints/attrs.js.map +1 -0
- package/dist/endpoints/entities.d.ts +9 -0
- package/dist/endpoints/entities.d.ts.map +1 -0
- package/dist/endpoints/entities.js +149 -0
- package/dist/endpoints/entities.js.map +1 -0
- package/dist/endpoints/subscriptions.d.ts +8 -0
- package/dist/endpoints/subscriptions.d.ts.map +1 -0
- package/dist/endpoints/subscriptions.js +109 -0
- package/dist/endpoints/subscriptions.js.map +1 -0
- package/dist/endpoints/types.d.ts +7 -0
- package/dist/endpoints/types.d.ts.map +1 -0
- package/dist/endpoints/types.js +45 -0
- package/dist/endpoints/types.js.map +1 -0
- package/dist/helpers/property.d.ts +33 -0
- package/dist/helpers/property.d.ts.map +1 -0
- package/dist/helpers/property.js +40 -0
- package/dist/helpers/property.js.map +1 -0
- package/dist/helpers/urn.d.ts +26 -0
- package/dist/helpers/urn.d.ts.map +1 -0
- package/dist/helpers/urn.js +30 -0
- package/dist/helpers/urn.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/models/agrifood/agri_parcel.d.ts +17 -0
- package/dist/models/agrifood/agri_parcel.d.ts.map +1 -0
- package/dist/models/agrifood/agri_parcel.js +27 -0
- package/dist/models/agrifood/agri_parcel.js.map +1 -0
- package/dist/models/agrifood/agri_soil_measurement.d.ts +17 -0
- package/dist/models/agrifood/agri_soil_measurement.d.ts.map +1 -0
- package/dist/models/agrifood/agri_soil_measurement.js +31 -0
- package/dist/models/agrifood/agri_soil_measurement.js.map +1 -0
- package/dist/models/agrifood/agri_weather_observed.d.ts +20 -0
- package/dist/models/agrifood/agri_weather_observed.d.ts.map +1 -0
- package/dist/models/agrifood/agri_weather_observed.js +34 -0
- package/dist/models/agrifood/agri_weather_observed.js.map +1 -0
- package/dist/models/device/device.d.ts +24 -0
- package/dist/models/device/device.d.ts.map +1 -0
- package/dist/models/device/device.js +39 -0
- package/dist/models/device/device.js.map +1 -0
- package/dist/models/device/device_measurement.d.ts +16 -0
- package/dist/models/device/device_measurement.d.ts.map +1 -0
- package/dist/models/device/device_measurement.js +34 -0
- package/dist/models/device/device_measurement.js.map +1 -0
- package/dist/models/environment/air_quality_observed.d.ts +22 -0
- package/dist/models/environment/air_quality_observed.d.ts.map +1 -0
- package/dist/models/environment/air_quality_observed.js +50 -0
- package/dist/models/environment/air_quality_observed.js.map +1 -0
- package/dist/models/environment/noise_level_observed.d.ts +17 -0
- package/dist/models/environment/noise_level_observed.d.ts.map +1 -0
- package/dist/models/environment/noise_level_observed.js +31 -0
- package/dist/models/environment/noise_level_observed.js.map +1 -0
- package/dist/models/environment/water_quality_observed.d.ts +20 -0
- package/dist/models/environment/water_quality_observed.d.ts.map +1 -0
- package/dist/models/environment/water_quality_observed.js +46 -0
- package/dist/models/environment/water_quality_observed.js.map +1 -0
- package/dist/models/environment/weather_observed.d.ts +19 -0
- package/dist/models/environment/weather_observed.d.ts.map +1 -0
- package/dist/models/environment/weather_observed.js +46 -0
- package/dist/models/environment/weather_observed.js.map +1 -0
- package/dist/models/index.d.ts +25 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +17 -0
- package/dist/models/index.js.map +1 -0
- package/dist/models/smart_city/parking_spot.d.ts +14 -0
- package/dist/models/smart_city/parking_spot.d.ts.map +1 -0
- package/dist/models/smart_city/parking_spot.js +27 -0
- package/dist/models/smart_city/parking_spot.js.map +1 -0
- package/dist/models/smart_city/street_light.d.ts +16 -0
- package/dist/models/smart_city/street_light.d.ts.map +1 -0
- package/dist/models/smart_city/street_light.js +33 -0
- package/dist/models/smart_city/street_light.js.map +1 -0
- package/dist/models/smart_city/traffic_flow_observed.d.ts +19 -0
- package/dist/models/smart_city/traffic_flow_observed.d.ts.map +1 -0
- package/dist/models/smart_city/traffic_flow_observed.js +37 -0
- package/dist/models/smart_city/traffic_flow_observed.js.map +1 -0
- package/dist/notifications/notification_sender.d.ts +16 -0
- package/dist/notifications/notification_sender.d.ts.map +1 -0
- package/dist/notifications/notification_sender.js +70 -0
- package/dist/notifications/notification_sender.js.map +1 -0
- package/dist/notifications/notification_worker.d.ts +19 -0
- package/dist/notifications/notification_worker.d.ts.map +1 -0
- package/dist/notifications/notification_worker.js +65 -0
- package/dist/notifications/notification_worker.js.map +1 -0
- package/dist/plugin.d.ts +35 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +113 -0
- package/dist/plugin.js.map +1 -0
- package/dist/subscriptions/q_parser.d.ts +42 -0
- package/dist/subscriptions/q_parser.d.ts.map +1 -0
- package/dist/subscriptions/q_parser.js +113 -0
- package/dist/subscriptions/q_parser.js.map +1 -0
- package/dist/subscriptions/subscription_cache.d.ts +46 -0
- package/dist/subscriptions/subscription_cache.d.ts.map +1 -0
- package/dist/subscriptions/subscription_cache.js +105 -0
- package/dist/subscriptions/subscription_cache.js.map +1 -0
- package/dist/subscriptions/subscription_matcher.d.ts +23 -0
- package/dist/subscriptions/subscription_matcher.d.ts.map +1 -0
- package/dist/subscriptions/subscription_matcher.js +84 -0
- package/dist/subscriptions/subscription_matcher.js.map +1 -0
- package/dist/subscriptions/subscription_store.d.ts +42 -0
- package/dist/subscriptions/subscription_store.d.ts.map +1 -0
- package/dist/subscriptions/subscription_store.js +189 -0
- package/dist/subscriptions/subscription_store.js.map +1 -0
- package/dist/types/context.d.ts +9 -0
- package/dist/types/context.d.ts.map +1 -0
- package/dist/types/context.js +5 -0
- package/dist/types/context.js.map +1 -0
- package/dist/types/entity.d.ts +46 -0
- package/dist/types/entity.d.ts.map +1 -0
- package/dist/types/entity.js +2 -0
- package/dist/types/entity.js.map +1 -0
- package/dist/types/notification.d.ts +22 -0
- package/dist/types/notification.d.ts.map +1 -0
- package/dist/types/notification.js +2 -0
- package/dist/types/notification.js.map +1 -0
- package/dist/types/subscription.d.ts +54 -0
- package/dist/types/subscription.d.ts.map +1 -0
- package/dist/types/subscription.js +2 -0
- package/dist/types/subscription.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { property } from '../../helpers/property.js';
|
|
2
|
+
import { buildUrn } from '../../helpers/urn.js';
|
|
3
|
+
import { NGSI_LD_CORE_CONTEXT } from '../../types/context.js';
|
|
4
|
+
/**
|
|
5
|
+
* Builds an NGSI-LD WeatherObserved entity.
|
|
6
|
+
*/
|
|
7
|
+
export function buildWeatherObserved(attrs) {
|
|
8
|
+
const entity = {
|
|
9
|
+
id: buildUrn('WeatherObserved', attrs.localId),
|
|
10
|
+
type: 'WeatherObserved',
|
|
11
|
+
'@context': NGSI_LD_CORE_CONTEXT,
|
|
12
|
+
};
|
|
13
|
+
const observedAt = attrs.dateObserved;
|
|
14
|
+
if (attrs.dateObserved !== undefined) {
|
|
15
|
+
entity['dateObserved'] = property(attrs.dateObserved);
|
|
16
|
+
}
|
|
17
|
+
if (attrs.temperature !== undefined) {
|
|
18
|
+
entity['temperature'] = property(attrs.temperature, observedAt ? { observedAt } : undefined);
|
|
19
|
+
}
|
|
20
|
+
if (attrs.relativeHumidity !== undefined) {
|
|
21
|
+
entity['relativeHumidity'] = property(attrs.relativeHumidity, observedAt ? { observedAt } : undefined);
|
|
22
|
+
}
|
|
23
|
+
if (attrs.windSpeed !== undefined) {
|
|
24
|
+
entity['windSpeed'] = property(attrs.windSpeed, observedAt ? { observedAt } : undefined);
|
|
25
|
+
}
|
|
26
|
+
if (attrs.windDirection !== undefined) {
|
|
27
|
+
entity['windDirection'] = property(attrs.windDirection, observedAt ? { observedAt } : undefined);
|
|
28
|
+
}
|
|
29
|
+
if (attrs.atmosphericPressure !== undefined) {
|
|
30
|
+
entity['atmosphericPressure'] = property(attrs.atmosphericPressure, observedAt ? { observedAt } : undefined);
|
|
31
|
+
}
|
|
32
|
+
if (attrs.precipitation !== undefined) {
|
|
33
|
+
entity['precipitation'] = property(attrs.precipitation, observedAt ? { observedAt } : undefined);
|
|
34
|
+
}
|
|
35
|
+
if (attrs.snowHeight !== undefined) {
|
|
36
|
+
entity['snowHeight'] = property(attrs.snowHeight, observedAt ? { observedAt } : undefined);
|
|
37
|
+
}
|
|
38
|
+
if (attrs.visibility !== undefined) {
|
|
39
|
+
entity['visibility'] = property(attrs.visibility, observedAt ? { observedAt } : undefined);
|
|
40
|
+
}
|
|
41
|
+
if (attrs.weatherType !== undefined) {
|
|
42
|
+
entity['weatherType'] = property(attrs.weatherType);
|
|
43
|
+
}
|
|
44
|
+
return entity;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=weather_observed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weather_observed.js","sourceRoot":"","sources":["../../../src/models/environment/weather_observed.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export { buildAirQualityObserved } from './environment/air_quality_observed.js';
|
|
2
|
+
export type { AirQualityObservedAttributes } from './environment/air_quality_observed.js';
|
|
3
|
+
export { buildWeatherObserved } from './environment/weather_observed.js';
|
|
4
|
+
export type { WeatherObservedAttributes } from './environment/weather_observed.js';
|
|
5
|
+
export { buildWaterQualityObserved } from './environment/water_quality_observed.js';
|
|
6
|
+
export type { WaterQualityObservedAttributes } from './environment/water_quality_observed.js';
|
|
7
|
+
export { buildNoiseLevelObserved } from './environment/noise_level_observed.js';
|
|
8
|
+
export type { NoiseLevelObservedAttributes } from './environment/noise_level_observed.js';
|
|
9
|
+
export { buildStreetLight } from './smart_city/street_light.js';
|
|
10
|
+
export type { StreetLightAttributes } from './smart_city/street_light.js';
|
|
11
|
+
export { buildParkingSpot } from './smart_city/parking_spot.js';
|
|
12
|
+
export type { ParkingSpotAttributes } from './smart_city/parking_spot.js';
|
|
13
|
+
export { buildTrafficFlowObserved } from './smart_city/traffic_flow_observed.js';
|
|
14
|
+
export type { TrafficFlowObservedAttributes } from './smart_city/traffic_flow_observed.js';
|
|
15
|
+
export { buildAgriParcel } from './agrifood/agri_parcel.js';
|
|
16
|
+
export type { AgriParcelAttributes } from './agrifood/agri_parcel.js';
|
|
17
|
+
export { buildAgriSoilMeasurement } from './agrifood/agri_soil_measurement.js';
|
|
18
|
+
export type { AgriSoilMeasurementAttributes } from './agrifood/agri_soil_measurement.js';
|
|
19
|
+
export { buildAgriWeatherObserved } from './agrifood/agri_weather_observed.js';
|
|
20
|
+
export type { AgriWeatherObservedAttributes } from './agrifood/agri_weather_observed.js';
|
|
21
|
+
export { buildDevice } from './device/device.js';
|
|
22
|
+
export type { DeviceAttributes } from './device/device.js';
|
|
23
|
+
export { buildDeviceMeasurement } from './device/device_measurement.js';
|
|
24
|
+
export type { DeviceMeasurementAttributes } from './device/device_measurement.js';
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAA;AAC/E,YAAY,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAA;AAEzF,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAA;AACxE,YAAY,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAA;AAElF,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAA;AACnF,YAAY,EAAE,8BAA8B,EAAE,MAAM,yCAAyC,CAAA;AAE7F,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAA;AAC/E,YAAY,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAA;AAGzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAC/D,YAAY,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AAEzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAC/D,YAAY,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AAEzE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAA;AAChF,YAAY,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAA;AAG1F,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAC3D,YAAY,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAErE,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAA;AAC9E,YAAY,EAAE,6BAA6B,EAAE,MAAM,qCAAqC,CAAA;AAExF,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAA;AAC9E,YAAY,EAAE,6BAA6B,EAAE,MAAM,qCAAqC,CAAA;AAGxF,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAE1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AACvE,YAAY,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Environment models
|
|
2
|
+
export { buildAirQualityObserved } from './environment/air_quality_observed.js';
|
|
3
|
+
export { buildWeatherObserved } from './environment/weather_observed.js';
|
|
4
|
+
export { buildWaterQualityObserved } from './environment/water_quality_observed.js';
|
|
5
|
+
export { buildNoiseLevelObserved } from './environment/noise_level_observed.js';
|
|
6
|
+
// Smart City models
|
|
7
|
+
export { buildStreetLight } from './smart_city/street_light.js';
|
|
8
|
+
export { buildParkingSpot } from './smart_city/parking_spot.js';
|
|
9
|
+
export { buildTrafficFlowObserved } from './smart_city/traffic_flow_observed.js';
|
|
10
|
+
// AgriFood models
|
|
11
|
+
export { buildAgriParcel } from './agrifood/agri_parcel.js';
|
|
12
|
+
export { buildAgriSoilMeasurement } from './agrifood/agri_soil_measurement.js';
|
|
13
|
+
export { buildAgriWeatherObserved } from './agrifood/agri_weather_observed.js';
|
|
14
|
+
// Device models
|
|
15
|
+
export { buildDevice } from './device/device.js';
|
|
16
|
+
export { buildDeviceMeasurement } from './device/device_measurement.js';
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AAAA,qBAAqB;AACrB,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAA;AAG/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAA;AAGxE,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAA;AAGnF,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAA;AAG/E,oBAAoB;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAG/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAA;AAG/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAA;AAGhF,kBAAkB;AAClB,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAG3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAA;AAG9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAA;AAG9E,gBAAgB;AAChB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGhD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { NgsiLdEntity } from '../../types/entity.js';
|
|
2
|
+
export interface ParkingSpotAttributes {
|
|
3
|
+
localId: string;
|
|
4
|
+
status?: 'free' | 'occupied' | 'closed' | 'unknown';
|
|
5
|
+
category?: string[];
|
|
6
|
+
refParkingSite?: string;
|
|
7
|
+
dateModified?: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Builds an NGSI-LD ParkingSpot entity.
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildParkingSpot(attrs: ParkingSpotAttributes): NgsiLdEntity;
|
|
14
|
+
//# sourceMappingURL=parking_spot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parking_spot.d.ts","sourceRoot":"","sources":["../../../src/models/smart_city/parking_spot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,uBAAuB,CAAA;AAKzE,MAAM,WAAW,qBAAqB;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAA;IACnD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,IAAI,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,YAAY,CAqB3E"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { property } from '../../helpers/property.js';
|
|
2
|
+
import { buildUrn } from '../../helpers/urn.js';
|
|
3
|
+
import { NGSI_LD_CORE_CONTEXT } from '../../types/context.js';
|
|
4
|
+
/**
|
|
5
|
+
* Builds an NGSI-LD ParkingSpot entity.
|
|
6
|
+
*/
|
|
7
|
+
export function buildParkingSpot(attrs) {
|
|
8
|
+
const entity = {
|
|
9
|
+
id: buildUrn('ParkingSpot', attrs.localId),
|
|
10
|
+
type: 'ParkingSpot',
|
|
11
|
+
'@context': NGSI_LD_CORE_CONTEXT,
|
|
12
|
+
};
|
|
13
|
+
if (attrs.status !== undefined) {
|
|
14
|
+
entity['status'] = property(attrs.status);
|
|
15
|
+
}
|
|
16
|
+
if (attrs.category !== undefined) {
|
|
17
|
+
entity['category'] = property(attrs.category);
|
|
18
|
+
}
|
|
19
|
+
if (attrs.name !== undefined) {
|
|
20
|
+
entity['name'] = property(attrs.name);
|
|
21
|
+
}
|
|
22
|
+
if (attrs.dateModified !== undefined) {
|
|
23
|
+
entity['dateModified'] = property(attrs.dateModified);
|
|
24
|
+
}
|
|
25
|
+
return entity;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=parking_spot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parking_spot.js","sourceRoot":"","sources":["../../../src/models/smart_city/parking_spot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAW7D;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAA4B;IACzD,MAAM,MAAM,GAAiB;QACzB,EAAE,EAAE,QAAQ,CAAC,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC;QAC1C,IAAI,EAAE,aAAa;QACnB,UAAU,EAAE,oBAAoB;KACnC,CAAA;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC7C,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAA6B,CAAA;IAC7E,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACzC,CAAC;IACD,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,CAAC,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IACzD,CAAC;IAED,OAAO,MAAM,CAAA;AACjB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { NgsiLdEntity } from '../../types/entity.js';
|
|
2
|
+
export interface StreetLightAttributes {
|
|
3
|
+
localId: string;
|
|
4
|
+
status?: 'ok' | 'defectiveLamp' | 'columnIssue' | 'ballastProblem' | 'okLampNotWorking' | 'vandalized';
|
|
5
|
+
powerState?: 'on' | 'off' | 'low' | 'bootingUp';
|
|
6
|
+
illuminanceLevel?: number;
|
|
7
|
+
powerConsumption?: number;
|
|
8
|
+
dateLastSwitchingOn?: string;
|
|
9
|
+
dateLastSwitchingOff?: string;
|
|
10
|
+
refStreetLightGroup?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Builds an NGSI-LD StreetLight entity.
|
|
14
|
+
*/
|
|
15
|
+
export declare function buildStreetLight(attrs: StreetLightAttributes): NgsiLdEntity;
|
|
16
|
+
//# sourceMappingURL=street_light.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"street_light.d.ts","sourceRoot":"","sources":["../../../src/models/smart_city/street_light.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,uBAAuB,CAAA;AAKzE,MAAM,WAAW,qBAAqB;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,IAAI,GAAG,eAAe,GAAG,aAAa,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,YAAY,CAAA;IACtG,UAAU,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,WAAW,CAAA;IAC/C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,YAAY,CA2B3E"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { property } from '../../helpers/property.js';
|
|
2
|
+
import { buildUrn } from '../../helpers/urn.js';
|
|
3
|
+
import { NGSI_LD_CORE_CONTEXT } from '../../types/context.js';
|
|
4
|
+
/**
|
|
5
|
+
* Builds an NGSI-LD StreetLight entity.
|
|
6
|
+
*/
|
|
7
|
+
export function buildStreetLight(attrs) {
|
|
8
|
+
const entity = {
|
|
9
|
+
id: buildUrn('StreetLight', attrs.localId),
|
|
10
|
+
type: 'StreetLight',
|
|
11
|
+
'@context': NGSI_LD_CORE_CONTEXT,
|
|
12
|
+
};
|
|
13
|
+
if (attrs.status !== undefined) {
|
|
14
|
+
entity['status'] = property(attrs.status);
|
|
15
|
+
}
|
|
16
|
+
if (attrs.powerState !== undefined) {
|
|
17
|
+
entity['powerState'] = property(attrs.powerState);
|
|
18
|
+
}
|
|
19
|
+
if (attrs.illuminanceLevel !== undefined) {
|
|
20
|
+
entity['illuminanceLevel'] = property(attrs.illuminanceLevel);
|
|
21
|
+
}
|
|
22
|
+
if (attrs.powerConsumption !== undefined) {
|
|
23
|
+
entity['powerConsumption'] = property(attrs.powerConsumption);
|
|
24
|
+
}
|
|
25
|
+
if (attrs.dateLastSwitchingOn !== undefined) {
|
|
26
|
+
entity['dateLastSwitchingOn'] = property(attrs.dateLastSwitchingOn);
|
|
27
|
+
}
|
|
28
|
+
if (attrs.dateLastSwitchingOff !== undefined) {
|
|
29
|
+
entity['dateLastSwitchingOff'] = property(attrs.dateLastSwitchingOff);
|
|
30
|
+
}
|
|
31
|
+
return entity;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=street_light.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"street_light.js","sourceRoot":"","sources":["../../../src/models/smart_city/street_light.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAa7D;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAA4B;IACzD,MAAM,MAAM,GAAiB;QACzB,EAAE,EAAE,QAAQ,CAAC,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC;QAC1C,IAAI,EAAE,aAAa;QACnB,UAAU,EAAE,oBAAoB;KACnC,CAAA;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC7C,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;IACrD,CAAC;IACD,IAAI,KAAK,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACvC,MAAM,CAAC,kBAAkB,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,gBAAgB,CAA2B,CAAA;IACnG,CAAC;IACD,IAAI,KAAK,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QACvC,MAAM,CAAC,kBAAkB,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,gBAAgB,CAA2B,CAAA;IACnG,CAAC;IACD,IAAI,KAAK,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;QAC1C,MAAM,CAAC,qBAAqB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAA;IACvE,CAAC;IACD,IAAI,KAAK,CAAC,oBAAoB,KAAK,SAAS,EAAE,CAAC;QAC3C,MAAM,CAAC,sBAAsB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAA;IACzE,CAAC;IAED,OAAO,MAAM,CAAA;AACjB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { NgsiLdEntity } from '../../types/entity.js';
|
|
2
|
+
export interface TrafficFlowObservedAttributes {
|
|
3
|
+
localId: string;
|
|
4
|
+
dateObserved?: string;
|
|
5
|
+
intensity?: number;
|
|
6
|
+
occupancy?: number;
|
|
7
|
+
averageVehicleSpeed?: number;
|
|
8
|
+
averageVehicleLength?: number;
|
|
9
|
+
congested?: boolean;
|
|
10
|
+
averageHeadwayTime?: number;
|
|
11
|
+
laneId?: number;
|
|
12
|
+
laneDirection?: string;
|
|
13
|
+
vehicleType?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Builds an NGSI-LD TrafficFlowObserved entity.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildTrafficFlowObserved(attrs: TrafficFlowObservedAttributes): NgsiLdEntity;
|
|
19
|
+
//# sourceMappingURL=traffic_flow_observed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traffic_flow_observed.d.ts","sourceRoot":"","sources":["../../../src/models/smart_city/traffic_flow_observed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,uBAAuB,CAAA;AAKzE,MAAM,WAAW,6BAA6B;IAC1C,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,WAAW,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,6BAA6B,GAAG,YAAY,CAgC3F"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { property } from '../../helpers/property.js';
|
|
2
|
+
import { buildUrn } from '../../helpers/urn.js';
|
|
3
|
+
import { NGSI_LD_CORE_CONTEXT } from '../../types/context.js';
|
|
4
|
+
/**
|
|
5
|
+
* Builds an NGSI-LD TrafficFlowObserved entity.
|
|
6
|
+
*/
|
|
7
|
+
export function buildTrafficFlowObserved(attrs) {
|
|
8
|
+
const entity = {
|
|
9
|
+
id: buildUrn('TrafficFlowObserved', attrs.localId),
|
|
10
|
+
type: 'TrafficFlowObserved',
|
|
11
|
+
'@context': NGSI_LD_CORE_CONTEXT,
|
|
12
|
+
};
|
|
13
|
+
const observedAt = attrs.dateObserved;
|
|
14
|
+
if (attrs.dateObserved !== undefined) {
|
|
15
|
+
entity['dateObserved'] = property(attrs.dateObserved);
|
|
16
|
+
}
|
|
17
|
+
if (attrs.intensity !== undefined) {
|
|
18
|
+
entity['intensity'] = property(attrs.intensity, observedAt ? { observedAt } : undefined);
|
|
19
|
+
}
|
|
20
|
+
if (attrs.occupancy !== undefined) {
|
|
21
|
+
entity['occupancy'] = property(attrs.occupancy, observedAt ? { observedAt } : undefined);
|
|
22
|
+
}
|
|
23
|
+
if (attrs.averageVehicleSpeed !== undefined) {
|
|
24
|
+
entity['averageVehicleSpeed'] = property(attrs.averageVehicleSpeed, observedAt ? { observedAt } : undefined);
|
|
25
|
+
}
|
|
26
|
+
if (attrs.congested !== undefined) {
|
|
27
|
+
entity['congested'] = property(attrs.congested);
|
|
28
|
+
}
|
|
29
|
+
if (attrs.laneId !== undefined) {
|
|
30
|
+
entity['laneId'] = property(attrs.laneId);
|
|
31
|
+
}
|
|
32
|
+
if (attrs.vehicleType !== undefined) {
|
|
33
|
+
entity['vehicleType'] = property(attrs.vehicleType);
|
|
34
|
+
}
|
|
35
|
+
return entity;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=traffic_flow_observed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traffic_flow_observed.js","sourceRoot":"","sources":["../../../src/models/smart_city/traffic_flow_observed.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAgB7D;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,KAAoC;IACzE,MAAM,MAAM,GAAiB;QACzB,EAAE,EAAE,QAAQ,CAAC,qBAAqB,EAAE,KAAK,CAAC,OAAO,CAAC;QAClD,IAAI,EAAE,qBAAqB;QAC3B,UAAU,EAAE,oBAAoB;KACnC,CAAA;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,YAAY,CAAA;IAErC,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,CAAC,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IACzD,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,CAAC,WAAW,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAA2B,CAAA;IAC9H,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,CAAC,WAAW,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAA2B,CAAA;IAC9H,CAAC;IACD,IAAI,KAAK,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;QAC1C,MAAM,CAAC,qBAAqB,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAAS,CAA2B,CAAA;IAClJ,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,CAAC,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IACnD,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,MAAM,CAA2B,CAAA;IAC/E,CAAC;IACD,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,CAAC,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;IACvD,CAAC;IAED,OAAO,MAAM,CAAA;AACjB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Queue } from 'bullmq';
|
|
2
|
+
import type { Subscription } from '../types/subscription.js';
|
|
3
|
+
import type { NgsiLdEntity } from '../types/entity.js';
|
|
4
|
+
import type { NotificationJobData } from '../types/notification.js';
|
|
5
|
+
/**
|
|
6
|
+
* Enqueues a notification delivery job in BullMQ.
|
|
7
|
+
*
|
|
8
|
+
* Constructs the appropriate payload (normalized or keyValues) and adds
|
|
9
|
+
* a job to the `ngsi-ld-notifications` queue.
|
|
10
|
+
*
|
|
11
|
+
* @param sub - The subscription to notify
|
|
12
|
+
* @param entity - The entity that triggered the notification
|
|
13
|
+
* @param queue - The BullMQ queue to enqueue into
|
|
14
|
+
*/
|
|
15
|
+
export declare function enqueueNotification(sub: Subscription, entity: NgsiLdEntity, queue: Queue<NotificationJobData>): Promise<void>;
|
|
16
|
+
//# sourceMappingURL=notification_sender.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification_sender.d.ts","sourceRoot":"","sources":["../../src/notifications/notification_sender.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,mBAAmB,EAAuB,MAAM,0BAA0B,CAAA;AAoBxF;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CACrC,GAAG,EAAE,YAAY,EACjB,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,KAAK,CAAC,mBAAmB,CAAC,GAClC,OAAO,CAAC,IAAI,CAAC,CA2Cf"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { randomUUID } from 'crypto';
|
|
2
|
+
/**
|
|
3
|
+
* Builds a keyValues projection of an NGSI-LD entity.
|
|
4
|
+
*/
|
|
5
|
+
function toKeyValues(entity) {
|
|
6
|
+
const result = {
|
|
7
|
+
id: entity.id,
|
|
8
|
+
type: entity.type,
|
|
9
|
+
};
|
|
10
|
+
for (const [key, value] of Object.entries(entity)) {
|
|
11
|
+
if (key === 'id' || key === 'type' || key === '@context')
|
|
12
|
+
continue;
|
|
13
|
+
if (value && typeof value === 'object' && 'type' in value && 'value' in value) {
|
|
14
|
+
result[key] = value.value;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Enqueues a notification delivery job in BullMQ.
|
|
21
|
+
*
|
|
22
|
+
* Constructs the appropriate payload (normalized or keyValues) and adds
|
|
23
|
+
* a job to the `ngsi-ld-notifications` queue.
|
|
24
|
+
*
|
|
25
|
+
* @param sub - The subscription to notify
|
|
26
|
+
* @param entity - The entity that triggered the notification
|
|
27
|
+
* @param queue - The BullMQ queue to enqueue into
|
|
28
|
+
*/
|
|
29
|
+
export async function enqueueNotification(sub, entity, queue) {
|
|
30
|
+
const notificationId = randomUUID();
|
|
31
|
+
const notifiedAt = new Date().toISOString();
|
|
32
|
+
// Project attributes if subscription specifies them
|
|
33
|
+
let entityToSend = entity;
|
|
34
|
+
if (sub.notificationAttrs && sub.notificationAttrs.length > 0) {
|
|
35
|
+
const projected = { id: entity.id, type: entity.type };
|
|
36
|
+
for (const attr of sub.notificationAttrs) {
|
|
37
|
+
if (entity[attr] !== undefined)
|
|
38
|
+
projected[attr] = entity[attr];
|
|
39
|
+
}
|
|
40
|
+
entityToSend = projected;
|
|
41
|
+
}
|
|
42
|
+
// Validate the endpoint URI before enqueueing
|
|
43
|
+
const endpoint = sub.notificationEndpoint;
|
|
44
|
+
if (!endpoint)
|
|
45
|
+
return;
|
|
46
|
+
const jobData = {
|
|
47
|
+
subscription: sub,
|
|
48
|
+
entity: entityToSend,
|
|
49
|
+
notificationId,
|
|
50
|
+
notifiedAt,
|
|
51
|
+
};
|
|
52
|
+
await queue.add('notify', jobData, {
|
|
53
|
+
attempts: 3,
|
|
54
|
+
backoff: {
|
|
55
|
+
type: 'exponential',
|
|
56
|
+
delay: 1000,
|
|
57
|
+
},
|
|
58
|
+
removeOnComplete: 100,
|
|
59
|
+
removeOnFail: 50,
|
|
60
|
+
});
|
|
61
|
+
// Build the full notification payload (for reference, stored in job data)
|
|
62
|
+
const _payload = {
|
|
63
|
+
id: `urn:ngsi-ld:Notification:${notificationId}`,
|
|
64
|
+
type: 'Notification',
|
|
65
|
+
subscriptionId: sub.id,
|
|
66
|
+
notifiedAt,
|
|
67
|
+
data: [sub.notificationFormat === 'keyValues' ? toKeyValues(entityToSend) : entityToSend],
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=notification_sender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification_sender.js","sourceRoot":"","sources":["../../src/notifications/notification_sender.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AAEnC;;GAEG;AACH,SAAS,WAAW,CAAC,MAAoB;IACrC,MAAM,MAAM,GAA4B;QACpC,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC,IAAI;KACpB,CAAA;IACD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAChD,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,UAAU;YAAE,SAAQ;QAClE,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;YAC5E,MAAM,CAAC,GAAG,CAAC,GAAI,KAA4B,CAAC,KAAK,CAAA;QACrD,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAA;AACjB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACrC,GAAiB,EACjB,MAAoB,EACpB,KAAiC;IAEjC,MAAM,cAAc,GAAG,UAAU,EAAE,CAAA;IACnC,MAAM,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IAE3C,oDAAoD;IACpD,IAAI,YAAY,GAAG,MAAM,CAAA;IACzB,IAAI,GAAG,CAAC,iBAAiB,IAAI,GAAG,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5D,MAAM,SAAS,GAAiB,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAA;QACpE,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,iBAAiB,EAAE,CAAC;YACvC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,SAAS;gBAAE,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA;QAClE,CAAC;QACD,YAAY,GAAG,SAAS,CAAA;IAC5B,CAAC;IAED,8CAA8C;IAC9C,MAAM,QAAQ,GAAG,GAAG,CAAC,oBAAoB,CAAA;IACzC,IAAI,CAAC,QAAQ;QAAE,OAAM;IAErB,MAAM,OAAO,GAAwB;QACjC,YAAY,EAAE,GAAG;QACjB,MAAM,EAAE,YAAY;QACpB,cAAc;QACd,UAAU;KACb,CAAA;IAED,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE;QAC/B,QAAQ,EAAE,CAAC;QACX,OAAO,EAAE;YACL,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,IAAI;SACd;QACD,gBAAgB,EAAE,GAAG;QACrB,YAAY,EAAE,EAAE;KACnB,CAAC,CAAA;IAEF,0EAA0E;IAC1E,MAAM,QAAQ,GAAwB;QAClC,EAAE,EAAE,4BAA4B,cAAc,EAAE;QAChD,IAAI,EAAE,cAAc;QACpB,cAAc,EAAE,GAAG,CAAC,EAAE;QACtB,UAAU;QACV,IAAI,EAAE,CAAC,GAAG,CAAC,kBAAkB,KAAK,WAAW,CAAC,CAAC,CAAE,WAAW,CAAC,YAAY,CAAkB,CAAC,CAAC,CAAC,YAAY,CAAC;KAC9G,CAAA;AACL,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Worker } from 'bullmq';
|
|
2
|
+
import type { ConnectionOptions } from 'bullmq';
|
|
3
|
+
import type { NotificationJobData } from '../types/notification.js';
|
|
4
|
+
import type { SubscriptionStore } from '../subscriptions/subscription_store.js';
|
|
5
|
+
import type { SubscriptionCache } from '../subscriptions/subscription_cache.js';
|
|
6
|
+
import type { Logger } from '@cepseudo/shared';
|
|
7
|
+
/**
|
|
8
|
+
* Starts the BullMQ worker that delivers NGSI-LD notifications.
|
|
9
|
+
*
|
|
10
|
+
* For each job:
|
|
11
|
+
* 1. Builds the NotificationPayload
|
|
12
|
+
* 2. HTTP POSTs to the subscriber's endpoint
|
|
13
|
+
* 3. Updates times_sent / times_failed / last_success_at in PostgreSQL
|
|
14
|
+
* 4. Updates last_notification_at in Redis
|
|
15
|
+
*
|
|
16
|
+
* Retry: exponential backoff — 1s → 5s → 25s (max 3 attempts via queue config)
|
|
17
|
+
*/
|
|
18
|
+
export declare function startNotificationWorker(redis: ConnectionOptions, store: SubscriptionStore, cache: SubscriptionCache, logger: Logger): Worker<NotificationJobData>;
|
|
19
|
+
//# sourceMappingURL=notification_worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification_worker.d.ts","sourceRoot":"","sources":["../../src/notifications/notification_worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAA;AAC/C,OAAO,KAAK,EAAE,mBAAmB,EAAuB,MAAM,0BAA0B,CAAA;AACxF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAA;AAC/E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAA;AAC/E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAI9C;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACnC,KAAK,EAAE,iBAAiB,EACxB,KAAK,EAAE,iBAAiB,EACxB,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,GACf,MAAM,CAAC,mBAAmB,CAAC,CAyD7B"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Worker } from 'bullmq';
|
|
2
|
+
const QUEUE_NAME = 'ngsi-ld-notifications';
|
|
3
|
+
/**
|
|
4
|
+
* Starts the BullMQ worker that delivers NGSI-LD notifications.
|
|
5
|
+
*
|
|
6
|
+
* For each job:
|
|
7
|
+
* 1. Builds the NotificationPayload
|
|
8
|
+
* 2. HTTP POSTs to the subscriber's endpoint
|
|
9
|
+
* 3. Updates times_sent / times_failed / last_success_at in PostgreSQL
|
|
10
|
+
* 4. Updates last_notification_at in Redis
|
|
11
|
+
*
|
|
12
|
+
* Retry: exponential backoff — 1s → 5s → 25s (max 3 attempts via queue config)
|
|
13
|
+
*/
|
|
14
|
+
export function startNotificationWorker(redis, store, cache, logger) {
|
|
15
|
+
const worker = new Worker(QUEUE_NAME, async (job) => {
|
|
16
|
+
const { subscription: sub, entity, notificationId, notifiedAt } = job.data;
|
|
17
|
+
const payload = {
|
|
18
|
+
id: `urn:ngsi-ld:Notification:${notificationId}`,
|
|
19
|
+
type: 'Notification',
|
|
20
|
+
subscriptionId: sub.id,
|
|
21
|
+
notifiedAt,
|
|
22
|
+
data: [entity],
|
|
23
|
+
};
|
|
24
|
+
let success = false;
|
|
25
|
+
try {
|
|
26
|
+
const response = await fetch(sub.notificationEndpoint, {
|
|
27
|
+
method: 'POST',
|
|
28
|
+
headers: {
|
|
29
|
+
'Content-Type': 'application/ld+json',
|
|
30
|
+
'Accept': 'application/json',
|
|
31
|
+
},
|
|
32
|
+
body: JSON.stringify(payload),
|
|
33
|
+
});
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
throw new Error(`HTTP ${response.status} from ${sub.notificationEndpoint}`);
|
|
36
|
+
}
|
|
37
|
+
success = true;
|
|
38
|
+
logger.info(`Notification delivered to ${sub.notificationEndpoint} for subscription ${sub.id}`);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
logger.warn(`Notification delivery failed for subscription ${sub.id}: ${err instanceof Error ? err.message : String(err)}`);
|
|
42
|
+
throw err; // Re-throw so BullMQ handles retry
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
// Update stats regardless of success/failure (best-effort)
|
|
46
|
+
try {
|
|
47
|
+
await store.recordNotification(sub.id, success, notifiedAt);
|
|
48
|
+
await cache.updateLastNotified(sub.id, notifiedAt);
|
|
49
|
+
}
|
|
50
|
+
catch (statsErr) {
|
|
51
|
+
logger.warn(`Failed to update notification stats for ${sub.id}: ${statsErr instanceof Error ? statsErr.message : String(statsErr)}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}, {
|
|
55
|
+
connection: redis,
|
|
56
|
+
concurrency: 5,
|
|
57
|
+
});
|
|
58
|
+
worker.on('failed', (job, err) => {
|
|
59
|
+
if (job) {
|
|
60
|
+
logger.warn(`Notification job ${job.id} failed permanently: ${err.message}`);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
return worker;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=notification_worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification_worker.js","sourceRoot":"","sources":["../../src/notifications/notification_worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAO/B,MAAM,UAAU,GAAG,uBAAuB,CAAA;AAE1C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,uBAAuB,CACnC,KAAwB,EACxB,KAAwB,EACxB,KAAwB,EACxB,MAAc;IAEd,MAAM,MAAM,GAAG,IAAI,MAAM,CACrB,UAAU,EACV,KAAK,EAAC,GAAG,EAAC,EAAE;QACR,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,GAAG,GAAG,CAAC,IAAI,CAAA;QAE1E,MAAM,OAAO,GAAwB;YACjC,EAAE,EAAE,4BAA4B,cAAc,EAAE;YAChD,IAAI,EAAE,cAAc;YACpB,cAAc,EAAE,GAAG,CAAC,EAAE;YACtB,UAAU;YACV,IAAI,EAAE,CAAC,MAAM,CAAC;SACjB,CAAA;QAED,IAAI,OAAO,GAAG,KAAK,CAAA;QACnB,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,oBAAoB,EAAE;gBACnD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACL,cAAc,EAAE,qBAAqB;oBACrC,QAAQ,EAAE,kBAAkB;iBAC/B;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;aAChC,CAAC,CAAA;YAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,SAAS,GAAG,CAAC,oBAAoB,EAAE,CAAC,CAAA;YAC/E,CAAC;YAED,OAAO,GAAG,IAAI,CAAA;YACd,MAAM,CAAC,IAAI,CAAC,6BAA6B,GAAG,CAAC,oBAAoB,qBAAqB,GAAG,CAAC,EAAE,EAAE,CAAC,CAAA;QACnG,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,iDAAiD,GAAG,CAAC,EAAE,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YAC3H,MAAM,GAAG,CAAA,CAAC,mCAAmC;QACjD,CAAC;gBAAS,CAAC;YACP,2DAA2D;YAC3D,IAAI,CAAC;gBACD,MAAM,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,CAAC,CAAA;gBAC3D,MAAM,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC,CAAA;YACtD,CAAC;YAAC,OAAO,QAAQ,EAAE,CAAC;gBAChB,MAAM,CAAC,IAAI,CAAC,2CAA2C,GAAG,CAAC,EAAE,KAAK,QAAQ,YAAY,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;YACxI,CAAC;QACL,CAAC;IACL,CAAC,EACD;QACI,UAAU,EAAE,KAAK;QACjB,WAAW,EAAE,CAAC;KACjB,CACJ,CAAA;IAED,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC7B,IAAI,GAAG,EAAE,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,oBAAoB,GAAG,CAAC,EAAE,wBAAwB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;QAChF,CAAC;IACL,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACjB,CAAC"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Router } from 'ultimate-express';
|
|
2
|
+
import type { DatabaseAdapter } from '@cepseudo/database';
|
|
3
|
+
import { Logger } from '@cepseudo/shared';
|
|
4
|
+
/**
|
|
5
|
+
* Configuration options for the NGSI-LD plugin.
|
|
6
|
+
*/
|
|
7
|
+
export interface NgsiLdPluginOptions {
|
|
8
|
+
/** Express Router from the engine */
|
|
9
|
+
router: Router;
|
|
10
|
+
/** Database adapter for subscription persistence */
|
|
11
|
+
db: DatabaseAdapter;
|
|
12
|
+
/** Redis connection config for entity cache and subscription cache */
|
|
13
|
+
redis: {
|
|
14
|
+
host: string;
|
|
15
|
+
port: number;
|
|
16
|
+
password?: string;
|
|
17
|
+
};
|
|
18
|
+
/** All components registered in the engine */
|
|
19
|
+
components: unknown[];
|
|
20
|
+
/** Logger instance */
|
|
21
|
+
logger: Logger;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Registers the NGSI-LD plugin with the Digital Twin engine.
|
|
25
|
+
*
|
|
26
|
+
* This function:
|
|
27
|
+
* 1. Connects to Redis
|
|
28
|
+
* 2. Runs the subscription table migration
|
|
29
|
+
* 3. Warms up the subscription cache
|
|
30
|
+
* 4. Registers NGSI-LD HTTP endpoints
|
|
31
|
+
* 5. Starts the notification worker
|
|
32
|
+
* 6. Listens to engineEventBus for component completion events
|
|
33
|
+
*/
|
|
34
|
+
export declare function registerNgsiLd(options: NgsiLdPluginOptions): Promise<void>;
|
|
35
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,MAAM,EAAkB,MAAM,kBAAkB,CAAA;AAczD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAA;IACd,oDAAoD;IACpD,EAAE,EAAE,eAAe,CAAA;IACnB,sEAAsE;IACtE,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACxD,8CAA8C;IAC9C,UAAU,EAAE,OAAO,EAAE,CAAA;IACrB,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoGhF"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Queue } from 'bullmq';
|
|
2
|
+
import { Redis } from 'ioredis';
|
|
3
|
+
import { engineEventBus } from '@cepseudo/shared';
|
|
4
|
+
import { EntityCache } from './cache/entity_cache.js';
|
|
5
|
+
import { SubscriptionStore } from './subscriptions/subscription_store.js';
|
|
6
|
+
import { SubscriptionCache } from './subscriptions/subscription_cache.js';
|
|
7
|
+
import { SubscriptionMatcher } from './subscriptions/subscription_matcher.js';
|
|
8
|
+
import { isNgsiLdCollector, isNgsiLdHarvester } from './components/type_guards.js';
|
|
9
|
+
import { enqueueNotification } from './notifications/notification_sender.js';
|
|
10
|
+
import { startNotificationWorker } from './notifications/notification_worker.js';
|
|
11
|
+
import { registerEntityEndpoints } from './endpoints/entities.js';
|
|
12
|
+
import { registerAttrsEndpoints } from './endpoints/attrs.js';
|
|
13
|
+
import { registerSubscriptionEndpoints } from './endpoints/subscriptions.js';
|
|
14
|
+
import { registerTypesEndpoints } from './endpoints/types.js';
|
|
15
|
+
/**
|
|
16
|
+
* Registers the NGSI-LD plugin with the Digital Twin engine.
|
|
17
|
+
*
|
|
18
|
+
* This function:
|
|
19
|
+
* 1. Connects to Redis
|
|
20
|
+
* 2. Runs the subscription table migration
|
|
21
|
+
* 3. Warms up the subscription cache
|
|
22
|
+
* 4. Registers NGSI-LD HTTP endpoints
|
|
23
|
+
* 5. Starts the notification worker
|
|
24
|
+
* 6. Listens to engineEventBus for component completion events
|
|
25
|
+
*/
|
|
26
|
+
export async function registerNgsiLd(options) {
|
|
27
|
+
const { router, db, redis: redisConfig, components, logger } = options;
|
|
28
|
+
// Connect to Redis
|
|
29
|
+
const redisConnection = new Redis({
|
|
30
|
+
host: redisConfig.host,
|
|
31
|
+
port: redisConfig.port,
|
|
32
|
+
password: redisConfig.password,
|
|
33
|
+
maxRetriesPerRequest: null,
|
|
34
|
+
enableReadyCheck: true,
|
|
35
|
+
});
|
|
36
|
+
// Create Redis connection for BullMQ (separate connection, same config)
|
|
37
|
+
const bullmqConnection = {
|
|
38
|
+
host: redisConfig.host,
|
|
39
|
+
port: redisConfig.port,
|
|
40
|
+
password: redisConfig.password,
|
|
41
|
+
};
|
|
42
|
+
// Initialize subsystems
|
|
43
|
+
const entityCache = new EntityCache(redisConnection);
|
|
44
|
+
const subscriptionStore = new SubscriptionStore(db);
|
|
45
|
+
const subscriptionCache = new SubscriptionCache(redisConnection);
|
|
46
|
+
const matcher = new SubscriptionMatcher(subscriptionCache);
|
|
47
|
+
// Run migration to create subscriptions table
|
|
48
|
+
await subscriptionStore.runMigration();
|
|
49
|
+
// Warm up subscription cache from database
|
|
50
|
+
const allSubs = await subscriptionStore.findAll();
|
|
51
|
+
await subscriptionCache.warmup(allSubs);
|
|
52
|
+
logger.info(`NGSI-LD plugin initialized: ${allSubs.length} subscriptions loaded`);
|
|
53
|
+
// BullMQ notification queue
|
|
54
|
+
const notificationQueue = new Queue('ngsi-ld-notifications', {
|
|
55
|
+
connection: bullmqConnection,
|
|
56
|
+
});
|
|
57
|
+
// Register HTTP endpoints
|
|
58
|
+
registerEntityEndpoints(router, entityCache, subscriptionStore, subscriptionCache);
|
|
59
|
+
registerAttrsEndpoints(router, entityCache);
|
|
60
|
+
registerSubscriptionEndpoints(router, subscriptionStore, subscriptionCache);
|
|
61
|
+
registerTypesEndpoints(router, entityCache);
|
|
62
|
+
// Start notification delivery worker
|
|
63
|
+
startNotificationWorker(bullmqConnection, subscriptionStore, subscriptionCache, logger);
|
|
64
|
+
// Listen to engine events for NGSI-LD-aware components
|
|
65
|
+
engineEventBus.on('component:event', async (event) => {
|
|
66
|
+
if (event.type !== 'collector:completed' &&
|
|
67
|
+
event.type !== 'harvester:completed') {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const component = components.find(c => {
|
|
71
|
+
if (!c || typeof c !== 'object')
|
|
72
|
+
return false;
|
|
73
|
+
const conf = c.getConfiguration?.();
|
|
74
|
+
return conf?.name === event.componentName;
|
|
75
|
+
});
|
|
76
|
+
if (!component)
|
|
77
|
+
return;
|
|
78
|
+
if (!isNgsiLdCollector(component) && !isNgsiLdHarvester(component))
|
|
79
|
+
return;
|
|
80
|
+
try {
|
|
81
|
+
// Get the latest record from database
|
|
82
|
+
const record = await db.getLatestByName(event.componentName);
|
|
83
|
+
if (!record)
|
|
84
|
+
return;
|
|
85
|
+
// Parse the data
|
|
86
|
+
const blob = await record.data();
|
|
87
|
+
let data;
|
|
88
|
+
try {
|
|
89
|
+
data = JSON.parse(blob.toString());
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
data = blob.toString();
|
|
93
|
+
}
|
|
94
|
+
// Convert to NGSI-LD entity
|
|
95
|
+
const entity = component.toNgsiLdEntity(data, record);
|
|
96
|
+
const oldEntity = await entityCache.get(entity.id);
|
|
97
|
+
// Update cache
|
|
98
|
+
await entityCache.set(entity);
|
|
99
|
+
// Evaluate subscriptions
|
|
100
|
+
const matchingSubIds = await matcher.match(entity, oldEntity ?? undefined);
|
|
101
|
+
for (const subId of matchingSubIds) {
|
|
102
|
+
const sub = await subscriptionCache.getById(subId);
|
|
103
|
+
if (sub) {
|
|
104
|
+
await enqueueNotification(sub, entity, notificationQueue);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
logger.warn(`NGSI-LD event processing failed for ${event.componentName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=plugin.js.map
|