@skedulo/pulse-solution-services 0.0.5 → 0.0.7

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 (84) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +478 -13
  3. package/dist/clients/artifact-client.js +1 -0
  4. package/dist/clients/availability-api-client.js +1 -0
  5. package/dist/clients/base-client.js +1 -1
  6. package/dist/clients/config-features-client.js +1 -0
  7. package/dist/clients/config-template-client.js +1 -0
  8. package/dist/clients/config-var-client.js +1 -1
  9. package/dist/clients/geo-api-client.js +1 -0
  10. package/dist/clients/graphql-client.js +1 -1
  11. package/dist/clients/index.js +1 -1
  12. package/dist/clients/mobile-notification-client.js +1 -0
  13. package/dist/clients/org-preference-client.js +1 -0
  14. package/dist/clients/vocabulary-client.js +1 -0
  15. package/dist/constants/artifact-constants.js +1 -0
  16. package/dist/constants/config-var-constants.js +1 -0
  17. package/dist/constants/http.js +1 -1
  18. package/dist/constants/index.js +1 -1
  19. package/dist/constants/mobile-notification-constants.js +1 -0
  20. package/dist/constants/tenant-endpoints.js +1 -1
  21. package/dist/constants/tenant-objects.js +1 -1
  22. package/dist/core/entity-factory.js +1 -0
  23. package/dist/core/execution-context.js +1 -1
  24. package/dist/core/index.js +1 -1
  25. package/dist/core/tenant-entities.js +1 -0
  26. package/dist/core/tenant-objects.js +1 -0
  27. package/dist/index.d.ts +850 -160
  28. package/dist/interfaces/artifacts.js +1 -0
  29. package/dist/interfaces/availability.js +1 -0
  30. package/dist/interfaces/config-template.js +1 -0
  31. package/dist/interfaces/geoservice-interfaces.js +1 -0
  32. package/dist/interfaces/index.js +1 -1
  33. package/dist/interfaces/mobile-notification.js +1 -0
  34. package/dist/interfaces/resource-availability.js +1 -0
  35. package/dist/interfaces/vocabulary.js +1 -0
  36. package/dist/logging/decorators/log-method.d.ts +2 -2
  37. package/dist/logging/decorators/log-method.js +1 -1
  38. package/dist/logging/logger.js +1 -1
  39. package/dist/logging/logging-utils.js +1 -0
  40. package/dist/services/cache/storage/config-var-cache-storage.js +1 -1
  41. package/dist/services/data-service.js +1 -0
  42. package/dist/services/geoservice.js +1 -0
  43. package/dist/services/graphql/graphql-query-builder.d.ts +21 -20
  44. package/dist/services/graphql/graphql-query-builder.js +1 -1
  45. package/dist/services/index.js +1 -1
  46. package/dist/services/metadata-service.js +1 -1
  47. package/dist/services/resource-availability/builder/data-service.d.ts +9 -0
  48. package/dist/services/resource-availability/builder/data-service.js +1 -0
  49. package/dist/services/resource-availability/builder/index.d.ts +3 -0
  50. package/dist/services/resource-availability/builder/index.js +1 -0
  51. package/dist/services/resource-availability/builder/resource-availability-service.d.ts +8 -0
  52. package/dist/services/resource-availability/builder/resource-availability-service.js +1 -0
  53. package/dist/services/resource-availability/builder/resource-builder.d.ts +17 -0
  54. package/dist/services/resource-availability/builder/resource-builder.js +1 -0
  55. package/dist/services/resource-availability/builder/resource-query-param.d.ts +23 -0
  56. package/dist/services/resource-availability/builder/resource-query-param.js +1 -0
  57. package/dist/services/resource-availability/index.d.ts +2 -0
  58. package/dist/services/resource-availability/index.js +1 -0
  59. package/dist/services/resource-availability/object-factory.d.ts +13 -0
  60. package/dist/services/resource-availability/object-factory.js +1 -0
  61. package/dist/services/resource-availability/resource-availability-service.d.ts +7 -0
  62. package/dist/services/resource-availability/resource-availability-service.js +1 -0
  63. package/dist/services/resource-availability/resource-builder.d.ts +16 -0
  64. package/dist/services/resource-availability/resource-builder.js +1 -0
  65. package/dist/services/resource-availability/resource-query-service.d.ts +7 -0
  66. package/dist/services/resource-availability/resource-query-service.js +1 -0
  67. package/dist/services/resource-availability/resource-validator.d.ts +29 -0
  68. package/dist/services/resource-availability/resource-validator.js +1 -0
  69. package/dist/services/resource-availability/validator/index.d.ts +3 -0
  70. package/dist/services/resource-availability/validator/index.js +1 -0
  71. package/dist/services/resource-availability/validator/resource-job-validation.d.ts +11 -0
  72. package/dist/services/resource-availability/validator/resource-job-validation.js +1 -0
  73. package/dist/services/resource-availability/validator/resource-validation-option.d.ts +5 -0
  74. package/dist/services/resource-availability/validator/resource-validation-option.js +1 -0
  75. package/dist/services/resource-availability/validator/resource-validator.d.ts +13 -0
  76. package/dist/services/resource-availability/validator/resource-validator.js +1 -0
  77. package/dist/services/resource-availability/validator/validation-result.d.ts +12 -0
  78. package/dist/services/resource-availability/validator/validation-result.js +1 -0
  79. package/dist/utils/datetime-utils.js +1 -0
  80. package/dist/utils/index.js +1 -1
  81. package/dist/utils/object-utils.js +1 -0
  82. package/package.json +6 -2
  83. package/yarn.lock +196 -3
  84. package/dist/constants/config-var.js +0 -1
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});
@@ -1 +1 @@
1
- "use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,r,i){void 0===i&&(i=r);var o=Object.getOwnPropertyDescriptor(t,r);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,i,o)}:function(e,t,r,i){void 0===i&&(i=r),e[i]=t[r]}),__exportStar=this&&this.__exportStar||function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||__createBinding(t,e,r)};Object.defineProperty(exports,"__esModule",{value:!0}),__exportStar(require("./config-var"),exports),__exportStar(require("./graphql"),exports),__exportStar(require("./metadata"),exports);
1
+ "use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(e,r,t,i){void 0===i&&(i=t);var o=Object.getOwnPropertyDescriptor(r,t);o&&!("get"in o?!r.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return r[t]}}),Object.defineProperty(e,i,o)}:function(e,r,t,i){void 0===i&&(i=t),e[i]=r[t]}),__exportStar=this&&this.__exportStar||function(e,r){for(var t in e)"default"===t||Object.prototype.hasOwnProperty.call(r,t)||__createBinding(r,e,t)};Object.defineProperty(exports,"__esModule",{value:!0}),__exportStar(require("../core/tenant-entities"),exports),__exportStar(require("./availability"),exports),__exportStar(require("./config-template"),exports),__exportStar(require("./config-var"),exports),__exportStar(require("./geoservice-interfaces"),exports),__exportStar(require("./graphql"),exports),__exportStar(require("./metadata"),exports),__exportStar(require("./mobile-notification"),exports);
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});
@@ -1,7 +1,7 @@
1
- export declare const PULSE_SOLUTION_NAMESPACE = "PSS";
2
1
  /**
3
2
  * This decorator logs the input arguments and output results of a method,
4
3
  * including error handling with ANSI color-coded logs for better console readability.
5
4
  * It allows selective logging based on the `LOG_NAMESPACE` environment variable.
5
+ * Uses Winston logger but retains ANSI colors for console logs.
6
6
  */
7
- export declare function LogMethod(namespace?: string): MethodDecorator;
7
+ export declare function LogMethod(namespace?: string): (target: any, propertyKey: any, descriptor: any) => any;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.PULSE_SOLUTION_NAMESPACE=void 0,exports.LogMethod=LogMethod,exports.PULSE_SOLUTION_NAMESPACE="PSS";const COLORS={RESET:"",GREEN:"",YELLOW:"",RED:"",CYAN:"",MAGENTA:""};function LogMethod(t=exports.PULSE_SOLUTION_NAMESPACE){return function(o,n,e){const O=e.value,r=process.env.LOG_NAMESPACE||"",E=parseInt(process.env.LOG_ENTRY_MAX_LENGTH||"120",10),S=r===t||"ALL"===r.toUpperCase();function s(o,n,e,O,r){const S=(new Date).toISOString(),s="ERROR"===o?COLORS.RED:"INPUT"===O?COLORS.CYAN:COLORS.MAGENTA;console.log(`${COLORS.GREEN}[${o}]${COLORS.RESET} | ${COLORS.YELLOW}${S}${COLORS.RESET} | ${COLORS.GREEN}${t}${COLORS.RESET} | ${n} | ${e} - ${s}${O}${COLORS.RESET}: ${function(t){if(!t)return"";const o="string"==typeof t?t:JSON.stringify(t);return o.length>E?`${o.substring(0,E-3)}...`:o}(r)}`)}return e.value=function(...t){S&&s("INFO",o.constructor.name,n.toString(),"INPUT",t);try{const e=O.apply(this,t);return e instanceof Promise?e.then((t=>(S&&s("INFO",o.constructor.name,n.toString(),"OUTPUT",t),t))):(S&&s("INFO",o.constructor.name,n.toString(),"OUTPUT",e),e)}catch(t){throw s("ERROR",o.constructor.name,n.toString(),"ERROR",t.message||t),t}},e}}
1
+ "use strict";var __awaiter=this&&this.__awaiter||function(t,n,e,o){return new(e||(e=Promise))((function(r,i){function s(t){try{O(o.next(t))}catch(t){i(t)}}function E(t){try{O(o.throw(t))}catch(t){i(t)}}function O(t){var n;t.done?r(t.value):(n=t.value,n instanceof e?n:new e((function(t){t(n)}))).then(s,E)}O((o=o.apply(t,n||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.LogMethod=LogMethod;const logging_utils_1=require("../logging-utils"),PULSE_SOLUTION_NAMESPACE="PSS",COLORS={RESET:"",GREEN:"",YELLOW:"",RED:"",CYAN:"",MAGENTA:""};function LogMethod(t=PULSE_SOLUTION_NAMESPACE){return function(n,e,o){const r=o.value,i=process.env.LOG_NAMESPACE||"";if(!i)return o;const s=parseInt(process.env.LOG_ENTRY_MAX_LENGTH||"120",10),E=i===t||"ALL"===i.toUpperCase();function O(t,n,e,o,r){const i=(new Date).toISOString(),E="ERROR"===o?COLORS.RED:"INPUT"===o?COLORS.CYAN:COLORS.MAGENTA;console.log(`${COLORS.GREEN}[${t.toUpperCase()}]${COLORS.RESET} | ${COLORS.YELLOW}${i}${COLORS.RESET} | ${COLORS.GREEN}${PULSE_SOLUTION_NAMESPACE}${COLORS.RESET} | ${n.constructor.name} | ${e} - ${E}${o}${COLORS.RESET}: ${function(t){if(!t)return"";const n=(0,logging_utils_1.maskSensitiveData)(t);return n.length>s?`${n.substring(0,s-3)}...`:n}(r)}`)}return o.value=function(...t){return __awaiter(this,void 0,void 0,(function*(){E&&O("info",this,e.toString(),"INPUT",t);try{const n=yield Promise.resolve(r.apply(this,t));return E&&O("info",this,e.toString(),"OUTPUT",n),n}catch(t){throw O("error",this,e.toString(),"ERROR",t.message||t),t}}))},o}}
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.Logger=void 0;class Logger{constructor(){this.logs=[]}info(e){this.logs.push({level:"info",message:e})}error(e){this.logs.push({level:"error",message:e}),console.error(`ERROR: ${this.getFormattedLogs()}`)}getLogs(){return this.logs}getFormattedLogs(e="\n"){return this.logs.map((e=>`${e.level.toUpperCase()}: ${e.message}`)).join(e)}clear(){this.logs=[]}}exports.Logger=Logger;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});const winston_1=require("winston"),devFormat=winston_1.format.printf((({timestamp:e,level:o,message:t})=>`[${e}] ${o.toUpperCase()}: ${t}`)),logger=(0,winston_1.createLogger)({level:process.env.LOG_LEVEL||"info",format:winston_1.format.combine(winston_1.format.timestamp({format:"YYYY-MM-DD HH:mm:ss"}),"production"===process.env.NODE_ENV?winston_1.format.json():devFormat),transports:[new winston_1.transports.Console]});exports.default=logger;
@@ -0,0 +1 @@
1
+ "use strict";function maskSensitiveData(e){if(!e)return e;const s=[/(?<=api[_-]?key[=:"'\s]*)[a-zA-Z0-9-_]+/gi,/(?<=secret[=:"'\s]*)[a-zA-Z0-9-_]+/gi,/(?<=password[=:"'\s]*)[^"'\s]+/gi,/(?<=Bearer[=:"'\s]*)[^"'\s]+/gi];let t="string"==typeof e?e:JSON.stringify(e);for(const e of s)t=t.replace(e,"*****");return t}Object.defineProperty(exports,"__esModule",{value:!0}),exports.maskSensitiveData=maskSensitiveData;
@@ -1 +1 @@
1
- "use strict";var __awaiter=this&&this.__awaiter||function(t,e,n,i){return new(n||(n=Promise))((function(r,o){function a(t){try{s(i.next(t))}catch(t){o(t)}}function c(t){try{s(i.throw(t))}catch(t){o(t)}}function s(t){var e;t.done?r(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,c)}s((i=i.apply(t,e||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConfigVarCacheStorage=void 0;const constants_1=require("../../../constants");class ConfigVarCacheStorage{constructor(t){this.configVarClient=t}set(t,e){return __awaiter(this,void 0,void 0,(function*(){try{yield this.configVarClient.create({key:t,value:e,configType:constants_1.CONFIG_VAR_TYPE.PLAIN_TEXT})}catch(n){yield this.configVarClient.update({key:t,value:e,configType:constants_1.CONFIG_VAR_TYPE.PLAIN_TEXT})}}))}get(t){return __awaiter(this,void 0,void 0,(function*(){var e;try{const e=yield this.configVarClient.get(t);if(e)return e.value}catch(t){if(null===(e=null==t?void 0:t.message)||void 0===e?void 0:e.includes("not_found"))return null;throw t}return null}))}delete(t){return __awaiter(this,void 0,void 0,(function*(){yield this.configVarClient.delete(t)}))}clear(){return __awaiter(this,void 0,void 0,(function*(){throw new Error("Clear operation is not supported by ConfigVarCacheStorage")}))}}exports.ConfigVarCacheStorage=ConfigVarCacheStorage;
1
+ "use strict";var __awaiter=this&&this.__awaiter||function(t,e,n,i){return new(n||(n=Promise))((function(o,r){function a(t){try{s(i.next(t))}catch(t){r(t)}}function c(t){try{s(i.throw(t))}catch(t){r(t)}}function s(t){var e;t.done?o(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(a,c)}s((i=i.apply(t,e||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ConfigVarCacheStorage=void 0;const config_var_constants_1=require("../../../constants/config-var-constants");class ConfigVarCacheStorage{constructor(t){this.configVarClient=t}set(t,e){return __awaiter(this,void 0,void 0,(function*(){try{yield this.configVarClient.create({key:t,value:e,configType:config_var_constants_1.ConfigVariableType.PLAIN_TEXT})}catch(n){yield this.configVarClient.update({key:t,value:e,configType:config_var_constants_1.ConfigVariableType.PLAIN_TEXT})}}))}get(t){return __awaiter(this,void 0,void 0,(function*(){var e;try{const e=yield this.configVarClient.get(t);if(e)return e.value}catch(t){if(null===(e=null==t?void 0:t.message)||void 0===e?void 0:e.includes("not_found"))return null;throw t}return null}))}delete(t){return __awaiter(this,void 0,void 0,(function*(){yield this.configVarClient.delete(t)}))}clear(){return __awaiter(this,void 0,void 0,(function*(){throw new Error("Clear operation is not supported by ConfigVarCacheStorage")}))}}exports.ConfigVarCacheStorage=ConfigVarCacheStorage;
@@ -0,0 +1 @@
1
+ "use strict";var __awaiter=this&&this.__awaiter||function(e,t,i,r){return new(i||(i=Promise))((function(a,o){function s(e){try{l(r.next(e))}catch(e){o(e)}}function n(e){try{l(r.throw(e))}catch(e){o(e)}}function l(e){var t;e.done?a(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(s,n)}l((r=r.apply(e,t||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.DataService=void 0;const graphql_1=require("./graphql");class DataService{constructor(e){this.graphqlService=e}getResources(e){return __awaiter(this,void 0,void 0,(function*(){const t=this.newQueryBuilder("Resources");return t.withFields(["UID","Name","Category","ResourceType","EmploymentType","UserId","PrimaryRegionId"]).withFilter("IsActive == true"),t.withParentQuery("PrimaryRegion").withFields(["UID","Name","Timezone"]),e.resourceIds&&e.resourceIds.size>0?t.withFilter(`UID IN ${JSON.stringify(Array.from(e.resourceIds))}`):e.regionIds&&e.regionIds.size>0&&t.withFilter(`PrimaryRegionId IN [${Array.from(e.regionIds).map((e=>`'${e}'`)).join(",")}]`),e.useTag&&t.withChildQuery("ResourceTags").withParentQuery("Tag").withFields(["UID","Name"]),e.useActivity&&t.withChildQuery("Activities").withFields(["UID","Name","Start","End","Type"]),e.useAvailability&&t.withChildQuery("Availabilities").withFields(["UID","Start","Finish","Type","IsAvailable"]),e.useJobAllocation&&t.withChildQuery("JobAllocations").withFields(["UID","Name","Start","End","JobId"]).withFilter("Status NOTIN ['Deleted', 'Declined']").withParentQuery("Job").withFields(["UID","Name","Start","End","Type"]),(yield t.execute()).records}))}getHolidays(e,t,i){return __awaiter(this,void 0,void 0,(function*(){const r={},a=t?t.toISOString().split("T")[0]:null,o=i?i.toISOString().split("T")[0]:null,s=this.newQueryBuilder("Holidays");s.withFields(["UID","Name","StartDate","EndDate","Global"]),s.withFilter("Global == true"),a&&s.withFilter(`EndDate >= ${a}`),o&&s.withFilter(`StartDate <= ${o}`);const n=yield s.execute();if(r.GLOBAL=n.records||[],e&&e.length>0){const t=this.newQueryBuilder("Holidays");t.withFields(["UID","Name","StartDate","EndDate"]),t.withChildQuery("HolidayRegions").withFields(["RegionId"]).withFilter(`RegionId IN [${e.map((e=>`'${e}'`)).join(",")}]`),a&&t.withFilter(`EndDate >= ${a}`),o&&t.withFilter(`StartDate <= ${o}`);const i=yield t.execute();for(const e of i.records||[])for(const t of e.HolidayRegions||[]){const i=t.RegionId;r[i]||(r[i]=[]),r[i].push(e)}}return r}))}newQueryBuilder(e){const t=new graphql_1.GraphQLQueryBuilder(e);return t.setGraphqlService(this.graphqlService),t}}exports.DataService=DataService;
@@ -0,0 +1 @@
1
+ "use strict";var __awaiter=this&&this.__awaiter||function(e,t,i,s){return new(i||(i=Promise))((function(r,n){function o(e){try{l(s.next(e))}catch(e){n(e)}}function a(e){try{l(s.throw(e))}catch(e){n(e)}}function l(e){var t;e.done?r(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(o,a)}l((s=s.apply(e,t||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.GeoService=void 0;const uuid_1=require("uuid");class GeoService{constructor(e){this.sessionId="",this.geoAPIClient=e,this.sessionId=this.generateNewSessionId()}getDistanceMatrix(e,t){return __awaiter(this,void 0,void 0,(function*(){const i=e.map((e=>({lat:parseFloat(this.stripTrailingZeros(e.lat)),lng:parseFloat(this.stripTrailingZeros(e.lng))}))),s=t.map((e=>({lat:parseFloat(this.stripTrailingZeros(e.lat)),lng:parseFloat(this.stripTrailingZeros(e.lng))}))),r=yield this.geoAPIClient.getDistanceMatrix({origins:i,destinations:s});if(!r||!r.matrix||0===r.matrix.length)throw new Error("Failed to retrieve distance matrix data");const n=new Map;for(let o=0;o<e.length;o++)for(let e=0;e<t.length;e++){const t=this.createKey(i[o],s[e]),a=r.matrix[o][e];n.set(t,a)}return n}))}getAddressSuggestions(e){return __awaiter(this,arguments,void 0,(function*(e,t=1){const i=e.sessionId||this.sessionId;e.sessionId||(e.sessionId=this.sessionId);const s=yield this.geoAPIClient.autocompleteAddress(e);if(0===s.predictions.length)return null;const r=s.predictions.slice(0,t);return Promise.all(r.map((e=>this.geoAPIClient.getPlaceDetails({placeId:e.placeId,sessionId:i}))))}))}getTimezone(e){return __awaiter(this,void 0,void 0,(function*(){return(yield this.geoAPIClient.getTimezone(e)).timeZoneId}))}generateNewSessionId(){return(0,uuid_1.v4)()}stripTrailingZeros(e){return parseFloat(e.toFixed(8)).toString()}createKey(e,t){return`${this.stripTrailingZeros(e.lat)},${this.stripTrailingZeros(e.lng)}-${this.stripTrailingZeros(t.lat)},${this.stripTrailingZeros(t.lng)}`}}exports.GeoService=GeoService;
@@ -1,4 +1,5 @@
1
- import { FetchRecordsQueryParams } from "../../interfaces/graphql";
1
+ import { FetchRecordsQueryParams, QueryResult } from "../../interfaces/graphql";
2
+ import { GraphQLService } from "./graphql-service";
2
3
  /**
3
4
  * A utility class for building GraphQL queries dynamically.
4
5
  */
@@ -13,6 +14,7 @@ export declare class GraphQLQueryBuilder {
13
14
  private parentQueries;
14
15
  private childQueries;
15
16
  private isParent;
17
+ private graphqlService;
16
18
  /**
17
19
  * Creates an instance of GraphQLQueryBuilder.
18
20
  * @param {string} objectName - The name of the object being queried.
@@ -20,56 +22,55 @@ export declare class GraphQLQueryBuilder {
20
22
  */
21
23
  constructor(objectName: string, isParent?: boolean);
22
24
  /**
23
- * Specifies the fields to be retrieved.
24
- * @param {string[]} fields - The list of fields to select.
25
- * @returns {this} - The query builder instance.
25
+ * Sets the GraphQL service to use for executing the query.
26
+ */
27
+ setGraphqlService(graphqlService: GraphQLService): void;
28
+ /**
29
+ * Specifies the fields to be retrieved. Prevents duplicates.
26
30
  */
27
31
  withFields(fields: string[]): this;
28
32
  /**
29
33
  * Adds a filter condition to the query.
30
- * @param {string} condition - The filter condition.
31
- * @returns {this} - The query builder instance.
32
34
  */
33
35
  withFilter(condition: string): this;
34
36
  /**
35
37
  * Sets a limit on the number of records to retrieve.
36
- * @param {number} first - The number of records to fetch.
37
- * @returns {this} - The query builder instance.
38
38
  */
39
39
  withLimit(first: number): this;
40
40
  /**
41
41
  * Sets an offset for pagination.
42
- * @param {number} offset - The offset value.
43
- * @returns {this} - The query builder instance.
44
42
  */
45
43
  withOffset(offset: number): this;
46
44
  /**
47
45
  * Sets the order in which records should be retrieved.
48
- * @param {string} orderBy - The field to order by.
49
- * @returns {this} - The query builder instance.
50
46
  */
51
47
  withOrderBy(orderBy: string): this;
52
48
  /**
53
49
  * Applies cursor-based pagination.
54
- * @param {string} after - The cursor position.
55
- * @returns {this} - The query builder instance.
56
50
  */
57
51
  withCursor(after: string): this;
58
52
  /**
59
53
  * Creates a parent query.
60
- * @param {string} objectName - The name of the parent object.
61
- * @returns {GraphQLQueryBuilder} - A new query builder instance for the parent.
62
54
  */
63
55
  withParentQuery(objectName: string): GraphQLQueryBuilder;
64
56
  /**
65
57
  * Creates a child query.
66
- * @param {string} objectName - The name of the child object.
67
- * @returns {GraphQLQueryBuilder} - A new query builder instance for the child.
68
58
  */
69
59
  withChildQuery(objectName: string): GraphQLQueryBuilder;
70
60
  /**
71
- * Builds the GraphQL query parameters.
72
- * @returns {FetchRecordsQueryParams} - The formatted query parameters.
61
+ * Recursively builds the GraphQL query fields, handling nested queries.
62
+ */
63
+ private formatQueryFields;
64
+ /**
65
+ * Builds the GraphQL query parameters in a more structured format.
73
66
  */
74
67
  build(): FetchRecordsQueryParams;
68
+ /**
69
+ * Executes the query using the GraphQL service, with improved error handling.
70
+ */
71
+ execute(): Promise<QueryResult>;
72
+ /**
73
+ * Generates a string representation of the GraphQL query for debugging.
74
+ */
75
+ toString(): string;
75
76
  }
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.GraphQLQueryBuilder=void 0;class GraphQLQueryBuilder{constructor(t,r=!1){this.fields=[],this.filters=[],this.parentQueries={},this.childQueries={},this.objectName=t.charAt(0).toLowerCase()+t.slice(1),this.isParent=r}withFields(t){return this.fields.push(...t),this}withFilter(t){if(this.isParent)throw new Error("Cannot apply filters to a parent query.");return this.filters.push(t),this}withLimit(t){if(this.isParent)throw new Error("Cannot apply limit to a parent query.");return this.first=t,this}withOffset(t){if(this.isParent)throw new Error("Cannot apply offset to a parent query.");return this.offset=t,this}withOrderBy(t){if(this.isParent)throw new Error("Cannot apply orderBy to a parent query.");return this.orderBy=t,this}withCursor(t){if(this.isParent)throw new Error("Cannot apply cursor to a parent query.");return this.after=t,this}withParentQuery(t){const r=new GraphQLQueryBuilder(t,!0);return this.parentQueries[t]=r,r}withChildQuery(t){const r=new GraphQLQueryBuilder(t);return this.childQueries[t]=r,r}build(){const t=Object.entries(this.parentQueries).map((([t,r])=>`${t} { ${r.build().fields} }`)),r=Object.entries(this.childQueries).map((([t,r])=>{const e=r.build();return`${t}${e.filter?` (filter: "${e.filter}")`:""} { ${e.fields} }`}));return{objectName:this.objectName,fields:[...this.fields,...t,...r].filter(Boolean).join(", "),filter:this.filters.length>0?this.filters.join(" AND "):void 0,first:this.first,offset:this.offset,orderBy:this.orderBy,after:this.after}}}exports.GraphQLQueryBuilder=GraphQLQueryBuilder;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.GraphQLQueryBuilder=void 0;class GraphQLQueryBuilder{constructor(r,e=!1){this.fields=new Set(["UID"]),this.filters=[],this.parentQueries={},this.childQueries={},this.graphqlService=null,this.objectName=r.charAt(0).toLowerCase()+r.slice(1),this.isParent=e}setGraphqlService(r){this.graphqlService=r}withFields(r){return r.forEach((r=>this.fields.add(r))),this}withFilter(r){if(this.isParent)throw new Error("Cannot apply filters to a parent query.");return this.filters.push(r),this}withLimit(r){if(this.isParent)throw new Error("Cannot apply limit to a parent query.");return this.first=r,this}withOffset(r){if(this.isParent)throw new Error("Cannot apply offset to a parent query.");return this.offset=r,this}withOrderBy(r){if(this.isParent)throw new Error("Cannot apply orderBy to a parent query.");return this.orderBy=r,this}withCursor(r){if(this.isParent)throw new Error("Cannot apply cursor to a parent query.");return this.after=r,this}withParentQuery(r){const e=new GraphQLQueryBuilder(r,!0);return this.parentQueries[r]=e,e}withChildQuery(r){const e=new GraphQLQueryBuilder(r);return this.childQueries[r]=e,e}formatQueryFields(){const r=Object.entries(this.parentQueries).map((([r,e])=>`${r} { ${e.formatQueryFields()} }`)).join(", "),e=Object.entries(this.childQueries).map((([r,e])=>{const t=e.build();return`${r} ${t.filter?`(filter: "${t.filter}")`:""} { ${t.fields} }`})).join(", ");return[...this.fields,r,e].filter(Boolean).join(", ")}build(){return{objectName:this.objectName,fields:this.formatQueryFields(),filter:this.filters.length>0?this.filters.join(" AND "):void 0,first:this.first,offset:this.offset,orderBy:this.orderBy,after:this.after}}execute(){return this.graphqlService?this.graphqlService.query(this.build()):Promise.reject(new Error("No GraphQL service set for query execution."))}toString(){return`{ ${this.objectName} { ${this.formatQueryFields()} } }`}}exports.GraphQLQueryBuilder=GraphQLQueryBuilder;
@@ -1 +1 @@
1
- "use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(e,r,t,o){void 0===o&&(o=t);var i=Object.getOwnPropertyDescriptor(r,t);i&&!("get"in i?!r.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return r[t]}}),Object.defineProperty(e,o,i)}:function(e,r,t,o){void 0===o&&(o=t),e[o]=r[t]}),__exportStar=this&&this.__exportStar||function(e,r){for(var t in e)"default"===t||Object.prototype.hasOwnProperty.call(r,t)||__createBinding(r,e,t)};Object.defineProperty(exports,"__esModule",{value:!0}),__exportStar(require("./batch-processor"),exports),__exportStar(require("./cache"),exports),__exportStar(require("./graphql"),exports),__exportStar(require("./metadata-service"),exports);
1
+ "use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(e,r,t,i){void 0===i&&(i=t);var o=Object.getOwnPropertyDescriptor(r,t);o&&!("get"in o?!r.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return r[t]}}),Object.defineProperty(e,i,o)}:function(e,r,t,i){void 0===i&&(i=t),e[i]=r[t]}),__exportStar=this&&this.__exportStar||function(e,r){for(var t in e)"default"===t||Object.prototype.hasOwnProperty.call(r,t)||__createBinding(r,e,t)};Object.defineProperty(exports,"__esModule",{value:!0}),__exportStar(require("./batch-processor"),exports),__exportStar(require("./cache"),exports),__exportStar(require("./graphql"),exports),__exportStar(require("./metadata-service"),exports),__exportStar(require("./resource-availability"),exports);
@@ -1 +1 @@
1
- "use strict";var __awaiter=this&&this.__awaiter||function(t,e,a,n){return new(a||(a=Promise))((function(i,r){function c(t){try{s(n.next(t))}catch(t){r(t)}}function o(t){try{s(n.throw(t))}catch(t){r(t)}}function s(t){var e;t.done?i(t.value):(e=t.value,e instanceof a?e:new a((function(t){t(e)}))).then(c,o)}s((n=n.apply(t,e||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.MetadataService=void 0;class MetadataService{constructor(t){this.client=t}getObjectMetadata(t){return __awaiter(this,void 0,void 0,(function*(){const e=(yield this.client.fetchAllMetadata()).result,a={};for(const n of t){const t=e.find((t=>t.name===n));if(!t)throw new Error(`Metadata mapping not found for object: ${n}`);a[n]=(yield this.client.fetchObjectMetadata(t.mapping)).result}return a}))}getPicklistValues(t){const e=t.fields.filter((t=>"picklist"===t.type)),a={};for(const t of e)a[t.name]=t.values.map((t=>t.value));return a}}exports.MetadataService=MetadataService;
1
+ "use strict";var __awaiter=this&&this.__awaiter||function(t,e,a,n){return new(a||(a=Promise))((function(i,r){function c(t){try{s(n.next(t))}catch(t){r(t)}}function o(t){try{s(n.throw(t))}catch(t){r(t)}}function s(t){var e;t.done?i(t.value):(e=t.value,e instanceof a?e:new a((function(t){t(e)}))).then(c,o)}s((n=n.apply(t,e||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.MetadataService=void 0;class MetadataService{constructor(t){this.client=t}getObjectMetadata(t){return __awaiter(this,void 0,void 0,(function*(){const e=yield this.client.fetchAllMetadata(),a={};for(const n of t){const t=e.find((t=>t.name===n));if(!t)throw new Error(`Metadata mapping not found for object: ${n}`);a[n]=yield this.client.fetchObjectMetadata(t.mapping)}return a}))}getPicklistValues(t){const e=t.fields.filter((t=>"picklist"===t.type)),a={};for(const t of e)a[t.name]=t.values.map((t=>t.value));return a}}exports.MetadataService=MetadataService;
@@ -0,0 +1,9 @@
1
+ import { GraphQLQueryBuilder, GraphQLService } from "../../graphql";
2
+ import { ResourceQueryParam } from "./resource-query-param";
3
+ export declare class DataService {
4
+ private graphqlService;
5
+ constructor(graphqlService: GraphQLService);
6
+ getResources(param: ResourceQueryParam): Promise<Record<string, any>[]>;
7
+ getHolidays(regionIds: string[], startTime?: Date, endTime?: Date): Promise<Record<string, any>>;
8
+ newQueryBuilder(objectName: string): GraphQLQueryBuilder;
9
+ }
@@ -0,0 +1 @@
1
+ "use strict";var __awaiter=this&&this.__awaiter||function(e,t,i,r){return new(i||(i=Promise))((function(s,n){function o(e){try{c(r.next(e))}catch(e){n(e)}}function a(e){try{c(r.throw(e))}catch(e){n(e)}}function c(e){var t;e.done?s(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(o,a)}c((r=r.apply(e,t||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.DataService=void 0;const core_1=require("../../../core"),graphql_1=require("../../graphql");class DataService{constructor(e){this.graphqlService=e}getResources(e){return __awaiter(this,void 0,void 0,(function*(){const t=this.newQueryBuilder(core_1.TenantObjects.Resources.Name);t.withFields(core_1.TenantObjects.Resources.Fields).withFilter("IsActive == true"),t.withParentQuery("PrimaryRegion").withFields(core_1.TenantObjects.Regions.Fields),e.resourceIds&&e.resourceIds.size>0?t.withFilter(`UID IN ${JSON.stringify(Array.from(e.resourceIds))}`):e.regionIds&&e.regionIds.size>0&&t.withFilter(`PrimaryRegionId IN [${Array.from(e.regionIds).map((e=>`'${e}'`)).join(",")}]`),e.useTag&&t.withChildQuery(core_1.TenantObjects.ResourceTags.Name).withParentQuery("Tag").withFields(core_1.TenantObjects.Tags.Fields),e.useActivity&&t.withChildQuery(core_1.TenantObjects.Activities.Name).withFields(core_1.TenantObjects.Activities.Fields),e.useAvailability&&t.withChildQuery(core_1.TenantObjects.Availabilities.Name).withFields(core_1.TenantObjects.Availabilities.Fields),e.useJobAllocation&&t.withChildQuery(core_1.TenantObjects.JobAllocations.Name).withFields(core_1.TenantObjects.JobAllocations.Fields).withFilter("Status NOTIN ['Deleted', 'Declined']").withParentQuery("Job").withFields(core_1.TenantObjects.Jobs.Fields);return(yield t.execute()).records}))}getHolidays(e,t,i){return __awaiter(this,void 0,void 0,(function*(){const r={},s=t?t.toISOString().split("T")[0]:null,n=i?i.toISOString().split("T")[0]:null,o=this.newQueryBuilder(core_1.TenantObjects.Holidays.Name);o.withFields(core_1.TenantObjects.Holidays.Fields),o.withFilter("Global == true"),s&&o.withFilter(`EndDate >= ${s}`),n&&o.withFilter(`StartDate <= ${n}`);const a=yield o.execute();if(r.GLOBAL=a.records||[],e&&e.length>0){const t=this.newQueryBuilder(core_1.TenantObjects.Holidays.Name);t.withFields(core_1.TenantObjects.Holidays.Fields),t.withChildQuery(core_1.TenantObjects.HolidayRegions.Name).withFields(core_1.TenantObjects.HolidayRegions.Fields).withFilter(`RegionId IN [${e.map((e=>`'${e}'`)).join(",")}]`),s&&t.withFilter(`EndDate >= ${s}`),n&&t.withFilter(`StartDate <= ${n}`);const i=yield t.execute();for(const e of i.records||[])for(const t of e.HolidayRegions||[]){const i=t.RegionId;r[i]||(r[i]=[]),r[i].push(e)}}return r}))}newQueryBuilder(e){const t=new graphql_1.GraphQLQueryBuilder(e);return t.setGraphqlService(this.graphqlService),t}}exports.DataService=DataService;
@@ -0,0 +1,3 @@
1
+ export * from "./resource-availability-service";
2
+ export * from "./resource-builder";
3
+ export * from "./resource-query-param";
@@ -0,0 +1 @@
1
+ "use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(e,r,t,i){void 0===i&&(i=t);var o=Object.getOwnPropertyDescriptor(r,t);o&&!("get"in o?!r.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return r[t]}}),Object.defineProperty(e,i,o)}:function(e,r,t,i){void 0===i&&(i=t),e[i]=r[t]}),__exportStar=this&&this.__exportStar||function(e,r){for(var t in e)"default"===t||Object.prototype.hasOwnProperty.call(r,t)||__createBinding(r,e,t)};Object.defineProperty(exports,"__esModule",{value:!0}),__exportStar(require("./resource-availability-service"),exports),__exportStar(require("./resource-builder"),exports),__exportStar(require("./resource-query-param"),exports);
@@ -0,0 +1,8 @@
1
+ import { AvailabilityAPIClient } from "../../../clients/availability-api-client";
2
+ import { BaseEvent } from "../../../interfaces";
3
+ import { ResourceQueryParam } from "./resource-query-param";
4
+ export declare class ResourceAvailabilityService {
5
+ private availabilityAPIClient;
6
+ constructor(availabilityAPIClient: AvailabilityAPIClient);
7
+ getAvailabilityPatterns(param: ResourceQueryParam): Promise<Map<string, BaseEvent[]>>;
8
+ }
@@ -0,0 +1 @@
1
+ "use strict";var __awaiter=this&&this.__awaiter||function(e,t,i,r){return new(i||(i=Promise))((function(a,n){function s(e){try{c(r.next(e))}catch(e){n(e)}}function o(e){try{c(r.throw(e))}catch(e){n(e)}}function c(e){var t;e.done?a(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(s,o)}c((r=r.apply(e,t||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ResourceAvailabilityService=void 0;class ResourceAvailabilityService{constructor(e){this.availabilityAPIClient=e}getAvailabilityPatterns(e){return __awaiter(this,void 0,void 0,(function*(){const t=yield this.availabilityAPIClient.fetchAvailability({resourceIds:Array.from(e.resourceIds||[]),start:e.startTime.toISOString(),end:e.endTime.toISOString(),mergedAvailabilities:!1,entries:!0}),i=new Map;return t.forEach((e=>{if(!e.entries)return;const t=e.entries.filter((e=>"pattern"===e.type)).map((e=>({id:`${e.start}_${e.end}`,name:`${e.name}(${e.type})`,start:e.start?new Date(e.start):new Date(0),finish:e.end?new Date(e.end):new Date(0),eventType:e.type})));i.set(e.resourceId,t)})),i}))}}exports.ResourceAvailabilityService=ResourceAvailabilityService;
@@ -0,0 +1,17 @@
1
+ import { Resource } from "../../../core/tenant-entities";
2
+ import { DataService } from "./data-service";
3
+ import { ResourceAvailabilityService } from "./resource-availability-service";
4
+ import { ResourceQueryParam } from "./resource-query-param";
5
+ export declare class ResourceBuilder {
6
+ private dataService;
7
+ private availabilityService;
8
+ constructor(dataService: DataService, availabilityService: ResourceAvailabilityService);
9
+ build(queryParam: ResourceQueryParam): Promise<Resource[]>;
10
+ private loadAvailabilityPatterns;
11
+ private loadActivityEvents;
12
+ private loadAvailabilityEvents;
13
+ private loadJobAllocationEvents;
14
+ private loadResourceShiftEvents;
15
+ private loadHolidayEvents;
16
+ protected buildMore(resources: Resource[]): Resource[];
17
+ }
@@ -0,0 +1 @@
1
+ "use strict";var __decorate=this&&this.__decorate||function(e,t,i,a){var r,s=arguments.length,o=s<3?t:null===a?a=Object.getOwnPropertyDescriptor(t,i):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,a);else for(var n=e.length-1;n>=0;n--)(r=e[n])&&(o=(s<3?r(o):s>3?r(t,i,o):r(t,i))||o);return s>3&&o&&Object.defineProperty(t,i,o),o},__metadata=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},__awaiter=this&&this.__awaiter||function(e,t,i,a){return new(i||(i=Promise))((function(r,s){function o(e){try{l(a.next(e))}catch(e){s(e)}}function n(e){try{l(a.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?r(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(o,n)}l((a=a.apply(e,t||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ResourceBuilder=void 0;const entity_factory_1=require("../../../core/entity-factory"),logging_1=require("../../../logging"),utils_1=require("../../../utils"),resource_query_param_1=require("./resource-query-param");class ResourceBuilder{constructor(e,t){this.dataService=e,this.availabilityService=t}build(e){return __awaiter(this,void 0,void 0,(function*(){var t,i;if(!e)throw new Error("ResourceBuilder Error: queryParam is required");const a=[],r=yield this.dataService.getResources(e);e.resourceIds&&0!==e.resourceIds.size||(e.resourceIds=new Set(r.map((e=>e.UID))));for(const t of r){const i=entity_factory_1.EntityFactory.createResource(t);a.push(i),e.useActivity&&this.loadActivityEvents(t,i),e.useAvailability&&this.loadAvailabilityEvents(t,i),e.useJobAllocation&&this.loadJobAllocationEvents(t,i),e.useResourceShift&&this.loadResourceShiftEvents(t,i),e.useHoliday&&this.loadHolidayEvents(i,e)}e.useAvailabilityPattern&&(yield this.loadAvailabilityPatterns(a,e));for(const r of a)e.mergeAvailability?r.availabilities=utils_1.DateTimeUtils.mergeEvents(r.availabilities):null===(t=r.availabilities)||void 0===t||t.sort(((e,t)=>e.start.getTime()-t.start.getTime())),e.mergeEvents?r.events=utils_1.DateTimeUtils.mergeEvents(r.events):null===(i=r.events)||void 0===i||i.sort(((e,t)=>e.start.getTime()-t.start.getTime()));return this.buildMore(a)}))}loadAvailabilityPatterns(e,t){return __awaiter(this,void 0,void 0,(function*(){const i=yield this.availabilityService.getAvailabilityPatterns(t);for(const t of e)t.availabilities.push(...i.get(t.id)||[])}))}loadActivityEvents(e,t){e.Activities&&t.events.push(...e.Activities.map((e=>({id:e.UID,name:e.Name,start:new Date(e.Start),finish:new Date(e.End),eventType:"activity"}))))}loadAvailabilityEvents(e,t){if(e.availabilities){const i=[],a=[];e.Availabilities.forEach((e=>{e.IsAvailable?i.push(entity_factory_1.EntityFactory.createBaseEvent(e)):a.push(entity_factory_1.EntityFactory.createBaseEvent(e))})),t.availabilities=i,t.events.push(...a)}}loadJobAllocationEvents(e,t){e.JobAllocations&&t.events.push(...e.JobAllocations.map((e=>({id:e.UID,name:e.Name,start:e.Start?new Date(e.Start):void 0,finish:e.End?new Date(e.End):void 0,eventType:"job_allocation"}))))}loadResourceShiftEvents(e,t){e.resourceShifts&&t.events.push(...e.resourceShifts.map((e=>({id:e.id,name:e.name,start:e.start?new Date(e.start):new Date(0),finish:e.finish?new Date(e.finish):new Date(0),eventType:"resource_shift"}))))}loadHolidayEvents(e,t){return __awaiter(this,void 0,void 0,(function*(){const i=yield this.dataService.getHolidays(Array.from(t.regionIds||[]),t.startTime,t.endTime),a=i.GLOBAL||[];i[e.regionId]&&a.push(...i[e.regionId]),a.forEach((i=>{let a=utils_1.DateTimeUtils.getStartOfDate(i.StartDate,e.timezone),r=utils_1.DateTimeUtils.getEndOfDate(i.EndDate,e.timezone);a<t.startTime&&(a=t.startTime),r>t.endTime&&(r=t.endTime),e.events.push({id:`${a.toISOString()}_${r.toISOString()}`,name:i.Name,start:a,finish:r,eventType:"holiday"})}))}))}buildMore(e){return e}}exports.ResourceBuilder=ResourceBuilder,__decorate([(0,logging_1.LogMethod)(),__metadata("design:type",Function),__metadata("design:paramtypes",[resource_query_param_1.ResourceQueryParam]),__metadata("design:returntype",Promise)],ResourceBuilder.prototype,"build",null);
@@ -0,0 +1,23 @@
1
+ export declare class ResourceQueryParam {
2
+ resourceIds?: Set<string>;
3
+ regionIds?: Set<string>;
4
+ startTime: Date;
5
+ endTime: Date;
6
+ timezone: string;
7
+ respectResourceTimezone: boolean;
8
+ mergeAvailability: boolean;
9
+ mergeEvents: boolean;
10
+ useTag: boolean;
11
+ useJobAllocation: boolean;
12
+ useResourceShift: boolean;
13
+ useActivity: boolean;
14
+ useAvailability: boolean;
15
+ useAvailabilityTemplate: boolean;
16
+ useAvailabilityPattern: boolean;
17
+ useHoliday: boolean;
18
+ excludedJAStatus: Set<string>;
19
+ excludedJobStatus: Set<string>;
20
+ availabilityStatus: Set<string>;
21
+ resourceTypes: Set<string>;
22
+ constructor();
23
+ }
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ResourceQueryParam=void 0;class ResourceQueryParam{constructor(){this.useJobAllocation=!0,this.useResourceShift=!0,this.useActivity=!0,this.useAvailability=!0,this.useHoliday=!0,this.mergeAvailability=!0,this.excludedJAStatus=new Set(["Deleted","Declined"]),this.excludedJobStatus=new Set(["Cancelled"]),this.availabilityStatus=new Set(["Approved"]),this.resourceTypes=new Set(["Person","Asset"]),this.useTag=!0,this.startTime=new Date,this.endTime=new Date(Date.now()+12096e5),this.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone,this.respectResourceTimezone=!0,this.mergeEvents=!1,this.useAvailabilityTemplate=!1,this.useAvailabilityPattern=!0}}exports.ResourceQueryParam=ResourceQueryParam;
@@ -0,0 +1,2 @@
1
+ export * from "./builder";
2
+ export * from "./validator";
@@ -0,0 +1 @@
1
+ "use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,r,i){void 0===i&&(i=r);var o=Object.getOwnPropertyDescriptor(t,r);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,i,o)}:function(e,t,r,i){void 0===i&&(i=r),e[i]=t[r]}),__exportStar=this&&this.__exportStar||function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||__createBinding(t,e,r)};Object.defineProperty(exports,"__esModule",{value:!0}),__exportStar(require("./builder"),exports),__exportStar(require("./validator"),exports);
@@ -0,0 +1,13 @@
1
+ import { Activity, Availability, BaseEvent, BaseObject, Job, JobAllocation, Resource, ResourceShift, Shift, Tag } from "../../interfaces/resource-availability";
2
+ export declare class ObjectFactory {
3
+ static createBaseObject(data: Record<string, string>): BaseObject;
4
+ static createBaseEvent(data: Record<string, string>): BaseEvent;
5
+ static createTag(data: Record<string, any>): Tag;
6
+ static createResource(data: Record<string, any>): Resource;
7
+ static createJob(data: Record<string, any>): Job;
8
+ static createAvailability(data: Record<string, any>): Availability;
9
+ static createActivity(data: Record<string, any>): Activity;
10
+ static createJobAllocation(data: Record<string, any>): JobAllocation;
11
+ static createResourceShift(data: Record<string, any>): ResourceShift;
12
+ static createShift(data: Record<string, any>): Shift;
13
+ }
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ObjectFactory=void 0;class ObjectFactory{static createBaseObject(e){return{id:e.UID||"",name:e.Name||"",propertyMap:{}}}static createBaseEvent(e){return e.Finish?e.Finish:e.End,Object.assign(Object.assign({},this.createBaseObject(e)),{start:new Date(e.Start),finish:new Date(e.Start),eventType:e.Type||""})}static createTag(e){return this.createBaseObject(e)}static createResource(e){var t;return Object.assign(Object.assign({},this.createBaseObject(e)),{category:e.Category||"",employmentType:e.EmploymentType||"",resourceType:e.ResourceType||"",userId:e.UserId||"",regionId:e.PrimaryRegionId||"",timezone:(null===(t=e.PrimaryRegion)||void 0===t?void 0:t.Timezone)||"",tags:(e.ResourceTags||[]).map((e=>this.createTag(e.Tag))),availabilities:[],events:[]})}static createJob(e){return Object.assign(Object.assign({},this.createBaseEvent(e)),{jobStatus:e.JobStatus||"",regionId:e.RegionId||"",contactId:e.ContactId||"",start:e.Start?new Date(e.Start):new Date(0),finish:e.Finish?new Date(e.Finish):new Date(0),geoLocation:e.GeoLocation||{lat:e.GeoLatitude,lng:e.GeoLongitude},address:e.Address,eventType:"job",tags:(e.JobTags||[]).map((e=>this.createTag(e.Tag)))})}static createAvailability(e){return Object.assign(Object.assign({},this.createBaseEvent(e)),{resourceId:e.resourceId||"",isAvailable:!0===e.isAvailable||"true"===e.isAvailable,status:e.status||"",availabilityType:e.availabilityType||""})}static createActivity(e){return Object.assign(Object.assign({},this.createBaseEvent(e)),{resourceId:e.resourceId||"",activityType:e.activityType||""})}static createJobAllocation(e){return Object.assign(Object.assign({},this.createBaseEvent(e)),{jobId:e.jobId||"",resourceId:e.resourceId||"",status:e.status||""})}static createResourceShift(e){return Object.assign(Object.assign({},this.createBaseEvent(e)),{resourceId:e.resourceId||"",shift:this.createShift(e.shift||{})})}static createShift(e){return Object.assign(Object.assign({},this.createBaseEvent(e)),{regionId:e.regionId||"",displayName:e.displayName||"",isDraft:!0===e.isDraft||"true"===e.isDraft})}}exports.ObjectFactory=ObjectFactory;
@@ -0,0 +1,7 @@
1
+ import { AvailabilityAPIClient } from "../../clients/availability-api-client";
2
+ import { BaseEvent, ResourceQueryParam } from "../../interfaces/resource-availability";
3
+ export declare class ResourceAvailabilityService {
4
+ private availabilityAPIClient;
5
+ constructor(availabilityAPIClient: AvailabilityAPIClient);
6
+ getAvailabilityPatterns(param: ResourceQueryParam): Promise<Map<string, BaseEvent[]>>;
7
+ }
@@ -0,0 +1 @@
1
+ "use strict";var __awaiter=this&&this.__awaiter||function(e,t,i,r){return new(i||(i=Promise))((function(a,n){function s(e){try{c(r.next(e))}catch(e){n(e)}}function o(e){try{c(r.throw(e))}catch(e){n(e)}}function c(e){var t;e.done?a(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(s,o)}c((r=r.apply(e,t||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ResourceAvailabilityService=void 0;class ResourceAvailabilityService{constructor(e){this.availabilityAPIClient=e}getAvailabilityPatterns(e){return __awaiter(this,void 0,void 0,(function*(){const t=yield this.availabilityAPIClient.fetchAvailability({resourceIds:Array.from(e.resourceIds||[]),start:e.startTime.toISOString(),end:e.endTime.toISOString(),mergedAvailabilities:!1,entries:!0}),i=new Map;return t.forEach((e=>{if(!e.entries)return;const t=e.entries.filter((e=>"pattern"===e.type)).map((e=>({id:`${e.start}_${e.end}`,name:`${e.name}(${e.type})`,start:e.start?new Date(e.start):new Date(0),finish:e.end?new Date(e.end):new Date(0),eventType:e.type})));i.set(e.resourceId,t)})),i}))}}exports.ResourceAvailabilityService=ResourceAvailabilityService;
@@ -0,0 +1,16 @@
1
+ import { Resource, ResourceQueryParam } from "../../interfaces/resource-availability";
2
+ import { DataService } from "../data-service";
3
+ import { ResourceAvailabilityService } from "./resource-availability-service";
4
+ export declare class ResourceBuilder {
5
+ private dataService;
6
+ private availabilityService;
7
+ constructor(dataService: DataService, availabilityService: ResourceAvailabilityService);
8
+ build(queryParam: ResourceQueryParam): Promise<Resource[]>;
9
+ private loadAvailabilityPatterns;
10
+ private loadActivityEvents;
11
+ private loadAvailabilityEvents;
12
+ private loadJobAllocationEvents;
13
+ private loadResourceShiftEvents;
14
+ private loadHolidayEvents;
15
+ protected buildMore(resources: Resource[]): Resource[];
16
+ }
@@ -0,0 +1 @@
1
+ "use strict";var __decorate=this&&this.__decorate||function(e,t,i,a){var r,s=arguments.length,o=s<3?t:null===a?a=Object.getOwnPropertyDescriptor(t,i):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,i,a);else for(var n=e.length-1;n>=0;n--)(r=e[n])&&(o=(s<3?r(o):s>3?r(t,i,o):r(t,i))||o);return s>3&&o&&Object.defineProperty(t,i,o),o},__metadata=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},__awaiter=this&&this.__awaiter||function(e,t,i,a){return new(i||(i=Promise))((function(r,s){function o(e){try{l(a.next(e))}catch(e){s(e)}}function n(e){try{l(a.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?r(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(o,n)}l((a=a.apply(e,t||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ResourceBuilder=void 0;const resource_availability_1=require("../../interfaces/resource-availability"),logging_1=require("../../logging"),utils_1=require("../../utils"),object_factory_1=require("./object-factory");class ResourceBuilder{constructor(e,t){this.dataService=e,this.availabilityService=t}build(e){return __awaiter(this,void 0,void 0,(function*(){var t,i;if(!e)throw new Error("ResourceBuilder Error: queryParam is required");const a=[],r=yield this.dataService.getResources(e);e.resourceIds&&0!==e.resourceIds.size||(e.resourceIds=new Set(r.map((e=>e.UID))));for(const t of r){const i=object_factory_1.ObjectFactory.createResource(t);a.push(i),e.useActivity&&this.loadActivityEvents(t,i),e.useAvailability&&this.loadAvailabilityEvents(t,i),e.useJobAllocation&&this.loadJobAllocationEvents(t,i),e.useResourceShift&&this.loadResourceShiftEvents(t,i),e.useHoliday&&this.loadHolidayEvents(i,e)}e.useAvailabilityPattern&&(yield this.loadAvailabilityPatterns(a,e));for(const r of a)e.mergeAvailability?r.availabilities=utils_1.DateTimeUtils.mergeEvents(r.availabilities):null===(t=r.availabilities)||void 0===t||t.sort(((e,t)=>e.start.getTime()-t.start.getTime())),e.mergeEvents?r.events=utils_1.DateTimeUtils.mergeEvents(r.events):null===(i=r.events)||void 0===i||i.sort(((e,t)=>e.start.getTime()-t.start.getTime()));return this.buildMore(a)}))}loadAvailabilityPatterns(e,t){return __awaiter(this,void 0,void 0,(function*(){const i=yield this.availabilityService.getAvailabilityPatterns(t);for(const t of e)t.availabilities.push(...i.get(t.id)||[])}))}loadActivityEvents(e,t){e.Activities&&t.events.push(...e.Activities.map((e=>({id:e.UID,name:e.Name,start:new Date(e.Start),finish:new Date(e.End),eventType:"activity"}))))}loadAvailabilityEvents(e,t){if(e.availabilities){const i=[],a=[];e.Availabilities.forEach((e=>{e.IsAvailable?i.push(object_factory_1.ObjectFactory.createBaseEvent(e)):a.push(object_factory_1.ObjectFactory.createBaseEvent(e))})),t.availabilities=i,t.events.push(...a)}}loadJobAllocationEvents(e,t){e.JobAllocations&&t.events.push(...e.JobAllocations.map((e=>({id:e.UID,name:e.Name,start:e.Start?new Date(e.Start):void 0,finish:e.End?new Date(e.End):void 0,eventType:"job_allocation"}))))}loadResourceShiftEvents(e,t){e.resourceShifts&&t.events.push(...e.resourceShifts.map((e=>({id:e.id,name:e.name,start:e.start?new Date(e.start):new Date(0),finish:e.finish?new Date(e.finish):new Date(0),eventType:"resource_shift"}))))}loadHolidayEvents(e,t){return __awaiter(this,void 0,void 0,(function*(){const i=yield this.dataService.getHolidays(Array.from(t.regionIds||[]),t.startTime,t.endTime),a=i.GLOBAL||[];i[e.regionId]&&a.push(...i[e.regionId]),a.forEach((i=>{let a=utils_1.DateTimeUtils.getStartOfDate(i.StartDate,e.timezone),r=utils_1.DateTimeUtils.getEndOfDate(i.EndDate,e.timezone);a<t.startTime&&(a=t.startTime),r>t.endTime&&(r=t.endTime),e.events.push({id:`${a.toISOString()}_${r.toISOString()}`,name:i.Name,start:a,finish:r,eventType:"holiday"})}))}))}buildMore(e){return e}}exports.ResourceBuilder=ResourceBuilder,__decorate([(0,logging_1.LogMethod)(),__metadata("design:type",Function),__metadata("design:paramtypes",[resource_availability_1.ResourceQueryParam]),__metadata("design:returntype",Promise)],ResourceBuilder.prototype,"build",null);
@@ -0,0 +1,7 @@
1
+ import { ResourceQueryParam } from "../../interfaces/resource-availability";
2
+ import { GraphQLQueryBuilder } from "../graphql";
3
+ export declare class ResourceQueryService {
4
+ private queryBuilder;
5
+ constructor(queryBuilder: GraphQLQueryBuilder);
6
+ getResources(param: ResourceQueryParam): Promise<Record<string, any>[]>;
7
+ }
@@ -0,0 +1 @@
1
+ "use strict";var __awaiter=this&&this.__awaiter||function(e,i,r,t){return new(r||(r=Promise))((function(s,u){function o(e){try{n(t.next(e))}catch(e){u(e)}}function a(e){try{n(t.throw(e))}catch(e){u(e)}}function n(e){var i;e.done?s(e.value):(i=e.value,i instanceof r?i:new r((function(e){e(i)}))).then(o,a)}n((t=t.apply(e,i||[])).next())}))};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ResourceQueryService=void 0;class ResourceQueryService{constructor(e){this.queryBuilder=e}getResources(e){return __awaiter(this,void 0,void 0,(function*(){return this.queryBuilder.withFields(["UID","Name","Category","ResourceType","EmploymentType","UserId","PrimaryRegionId"]).withFilter("IsActive == true"),this.queryBuilder.withParentQuery("PrimaryRegion").withFields(["UID","Name","Timezone"]),e.resourceIds&&e.resourceIds.size>0?this.queryBuilder.withFilter(`UID IN ${JSON.stringify(Array.from(e.resourceIds))}`):e.regionIds&&e.regionIds.size>0&&this.queryBuilder.withFilter(`PrimaryRegionId IN ${JSON.stringify(Array.from(e.regionIds))}`),e.useTag&&this.queryBuilder.withChildQuery("ResourceTags").withParentQuery("Tag").withFields(["UID","Name"]),e.useActivity&&this.queryBuilder.withChildQuery("Activities").withFields(["UID","Name","Start","End","Type"]),e.useAvailability&&this.queryBuilder.withChildQuery("Availabilities").withFields(["UID","Start","Finish","Type","IsAvailable"]),e.useJobAllocation&&this.queryBuilder.withChildQuery("JobAllocations").withFields(["UID","Name","Start","End","JobId"]).withFilter("Status NOTIN ['Deleted', 'Declined']").withParentQuery("Job").withFields(["UID","Name","Start","End","Type"]),(yield this.queryBuilder.execute()).records}))}}exports.ResourceQueryService=ResourceQueryService;
@@ -0,0 +1,29 @@
1
+ import { BaseEvent, Job, Resource, ResourceValidationOption, Tag } from "../../interfaces";
2
+ declare class ResourceJobValidation {
3
+ resource: Resource;
4
+ job: Job;
5
+ availableEvent: BaseEvent | null;
6
+ conflictEvents: BaseEvent[];
7
+ missingTags: Tag[];
8
+ constructor(resource: Resource, job: Job, availableEvent?: BaseEvent | null, conflictEvents?: BaseEvent[], missingTags?: Tag[]);
9
+ isQualified(option: ResourceValidationOption): boolean;
10
+ }
11
+ export declare class ValidationResult {
12
+ private readonly validations;
13
+ private readonly option;
14
+ constructor(validations: ResourceJobValidation[], option: ResourceValidationOption);
15
+ getQualifiedResources(): Resource[];
16
+ getJobsWithXQualifiedResources(minQualifiedResources: number): Job[];
17
+ getUnqualifiedJobsWithReasons(): ResourceJobValidation[];
18
+ }
19
+ export declare class ResourceValidator {
20
+ private readonly option;
21
+ constructor(option: ResourceValidationOption);
22
+ validate(resources: Resource[], jobs: Job[]): ValidationResult;
23
+ private validateResource;
24
+ private findAvailableEvent;
25
+ private findConflictingEvents;
26
+ private findMissingTags;
27
+ private prepareData;
28
+ }
29
+ export {};
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ResourceValidator=exports.ValidationResult=void 0;const utils_1=require("../../utils");class ResourceJobValidation{constructor(i,t,s=null,e=[],o=[]){this.resource=i,this.job=t,this.availableEvent=s,this.conflictEvents=e,this.missingTags=o}isQualified(i){return!(i.checkAvailability&&null===this.availableEvent||i.checkConflict&&0!==this.conflictEvents.length||i.checkTag&&0!==this.missingTags.length)}}class ValidationResult{constructor(i,t){this.validations=i,this.option=t}getQualifiedResources(){const i=new Map;for(const t of this.validations)t.isQualified(this.option)&&i.set(t.resource.id,t.resource);return Array.from(i.values())}getJobsWithXQualifiedResources(i){const t=new Map;for(const i of this.validations)i.isQualified(this.option)&&t.set(i.job.id,(t.get(i.job.id)||0)+1);return Array.from(new Set(this.validations.map((i=>i.job)))).filter((s=>(t.get(s.id)||0)>=i))}getUnqualifiedJobsWithReasons(){return this.validations.filter((i=>!i.isQualified(this.option)))}}exports.ValidationResult=ValidationResult;class ResourceValidator{constructor(i){this.option=i}validate(i,t){if(!i.length||!t.length)throw new Error("ResourceValidator Error: Resources and jobs must be provided before validation.");this.prepareData(i,t);const s=[];for(const e of t)for(const t of i)s.push(this.validateResource(t,e));return new ValidationResult(s,this.option)}validateResource(i,t){const s=new ResourceJobValidation(i,t);return this.option.checkAvailability&&(s.availableEvent=this.findAvailableEvent(i,t)),this.option.checkConflict&&(s.conflictEvents=this.findConflictingEvents(i,t)),this.option.checkTag&&(s.missingTags=this.findMissingTags(i,t)),s}findAvailableEvent(i,t){return i.availabilities.find((i=>utils_1.DateTimeUtils.isIncluding(i,t)))||null}findConflictingEvents(i,t){return i.events.filter((i=>i.id!==t.id&&utils_1.DateTimeUtils.isOverlapping(i,t)))}findMissingTags(i,t){if(!t.tags||!i.tags)return[];const s=new Set(i.tags.map((i=>i.id)));return t.tags.filter((i=>!s.has(i.id)))}prepareData(i,t){for(const t of i)t.tags||(t.tags=[]);for(const i of t)i.id||(i.id=`${i.start}-${i.finish}`),i.name||(i.name=`${i.start}-${i.finish}`),i.tags||(i.tags=[])}}exports.ResourceValidator=ResourceValidator;
@@ -0,0 +1,3 @@
1
+ export * from "./resource-job-validation";
2
+ export * from "./resource-validator";
3
+ export * from "./validation-result";
@@ -0,0 +1 @@
1
+ "use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(e,r,t,i){void 0===i&&(i=t);var o=Object.getOwnPropertyDescriptor(r,t);o&&!("get"in o?!r.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return r[t]}}),Object.defineProperty(e,i,o)}:function(e,r,t,i){void 0===i&&(i=t),e[i]=r[t]}),__exportStar=this&&this.__exportStar||function(e,r){for(var t in e)"default"===t||Object.prototype.hasOwnProperty.call(r,t)||__createBinding(r,e,t)};Object.defineProperty(exports,"__esModule",{value:!0}),__exportStar(require("./resource-job-validation"),exports),__exportStar(require("./resource-validator"),exports),__exportStar(require("./validation-result"),exports);
@@ -0,0 +1,11 @@
1
+ import { BaseEvent, Job, Resource, Tag } from "../../../interfaces";
2
+ import { ResourceValidationOption } from "./resource-validation-option";
3
+ export declare class ResourceJobValidation {
4
+ resource: Partial<Resource>;
5
+ job: Partial<Job>;
6
+ availableEvent: BaseEvent | null;
7
+ conflictEvents: BaseEvent[];
8
+ missingTags: Tag[];
9
+ constructor(resource: Partial<Resource>, job: Partial<Job>, availableEvent?: BaseEvent | null, conflictEvents?: BaseEvent[], missingTags?: Tag[]);
10
+ isQualified(option: ResourceValidationOption): boolean;
11
+ }
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ResourceJobValidation=void 0;class ResourceJobValidation{constructor(e,i,s=null,t=[],o=[]){this.resource=e,this.job=i,this.availableEvent=s,this.conflictEvents=t,this.missingTags=o,this.resource={id:e.id,name:e.name},this.job={id:i.id,name:i.name}}isQualified(e){return!(e.checkAvailability&&null===this.availableEvent||e.checkConflict&&0!==this.conflictEvents.length||e.checkTag&&0!==this.missingTags.length)}}exports.ResourceJobValidation=ResourceJobValidation;
@@ -0,0 +1,5 @@
1
+ export interface ResourceValidationOption {
2
+ checkAvailability: boolean;
3
+ checkConflict: boolean;
4
+ checkTag: boolean;
5
+ }
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});
@@ -0,0 +1,13 @@
1
+ import { Job, Resource } from "../../../interfaces";
2
+ import { ResourceValidationOption } from "./resource-validation-option";
3
+ import { ValidationResult } from "./validation-result";
4
+ export declare class ResourceValidator {
5
+ private readonly option;
6
+ constructor(option: ResourceValidationOption);
7
+ validate(resources: Resource[], jobs: Job[]): ValidationResult;
8
+ private validateResource;
9
+ private findAvailableEvent;
10
+ private findConflictingEvents;
11
+ private findMissingTags;
12
+ private prepareData;
13
+ }
@@ -0,0 +1 @@
1
+ "use strict";var __decorate=this&&this.__decorate||function(t,e,i,a){var o,r=arguments.length,n=r<3?e:null===a?a=Object.getOwnPropertyDescriptor(e,i):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(t,e,i,a);else for(var s=t.length-1;s>=0;s--)(o=t[s])&&(n=(r<3?o(n):r>3?o(e,i,n):o(e,i))||n);return r>3&&n&&Object.defineProperty(e,i,n),n},__metadata=this&&this.__metadata||function(t,e){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(t,e)};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ResourceValidator=void 0;const logging_1=require("../../../logging"),utils_1=require("../../../utils"),resource_job_validation_1=require("./resource-job-validation"),validation_result_1=require("./validation-result");class ResourceValidator{constructor(t){this.option=t}validate(t,e){if(!t.length||!e.length)throw new Error("ResourceValidator Error: Resources and jobs must be provided before validation.");this.prepareData(t,e);const i=[];for(const a of e)for(const e of t)i.push(this.validateResource(e,a));return new validation_result_1.ValidationResult(i,this.option)}validateResource(t,e){const i=new resource_job_validation_1.ResourceJobValidation(t,e);return this.option.checkAvailability&&(i.availableEvent=this.findAvailableEvent(t,e)),this.option.checkConflict&&(i.conflictEvents=this.findConflictingEvents(t,e)),this.option.checkTag&&(i.missingTags=this.findMissingTags(t,e)),i}findAvailableEvent(t,e){return t.availabilities.find((t=>utils_1.DateTimeUtils.isIncluding(t,e)))||null}findConflictingEvents(t,e){return t.events.filter((t=>t.id!==e.id&&utils_1.DateTimeUtils.isOverlapping(t,e)))}findMissingTags(t,e){if(!e.tags||!t.tags)return[];const i=new Set(t.tags.map((t=>t.id)));return e.tags.filter((t=>!i.has(t.id)))}prepareData(t,e){for(const e of t)e.tags||(e.tags=[]);for(const t of e)t.id||(t.id=`${t.start}-${t.finish}`),t.name||(t.name=`${t.start}-${t.finish}`),t.tags||(t.tags=[])}}exports.ResourceValidator=ResourceValidator,__decorate([(0,logging_1.LogMethod)(),__metadata("design:type",Function),__metadata("design:paramtypes",[Array,Array]),__metadata("design:returntype",validation_result_1.ValidationResult)],ResourceValidator.prototype,"validate",null);
@@ -0,0 +1,12 @@
1
+ import { Job, Resource } from "../../../interfaces";
2
+ import { ResourceJobValidation } from "./resource-job-validation";
3
+ import { ResourceValidationOption } from "./resource-validation-option";
4
+ export declare class ValidationResult {
5
+ private readonly validations;
6
+ private readonly option;
7
+ constructor(validations: ResourceJobValidation[], option: ResourceValidationOption);
8
+ getQualifiedResources(): Partial<Resource>[];
9
+ getJobsWithXQualifiedResources(minQualifiedResources: number): Partial<Job>[];
10
+ getUnqualifiedJobsWithReasons(): ResourceJobValidation[];
11
+ format(): any[];
12
+ }
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ValidationResult=void 0;class ValidationResult{constructor(i,e){this.validations=i,this.option=e}getQualifiedResources(){const i=new Map;for(const e of this.validations)e.isQualified(this.option)&&e.resource.id&&i.set(e.resource.id,e.resource);return Array.from(i.values())}getJobsWithXQualifiedResources(i){const e=new Map;for(const i of this.validations)i.isQualified(this.option)&&i.job.id&&e.set(i.job.id,(e.get(i.job.id)||0)+1);return Array.from(new Set(this.validations.map((i=>i.job)))).filter((t=>(e.get(t.id)||0)>=i))}getUnqualifiedJobsWithReasons(){return this.validations.filter((i=>!i.isQualified(this.option)))}format(){return this.validations.map((i=>({resource:i.resource,job:i.job,qualificationStatus:i.isQualified({checkAvailability:!0,checkConflict:!0,checkTag:!0})?"Qualified":"Not Qualified",reasons:[...i.availableEvent?[]:[{reason:"Resource is not available during the job timeframe."}],...i.conflictEvents.length>0?[{reason:"Conflict Detected",conflictingEvents:i.conflictEvents.map((i=>({id:i.id,name:i.name,eventType:i.eventType})))}]:[],...i.missingTags.length>0?[{reason:"Missing Required Skills",missingSkills:i.missingTags.map((i=>({id:i.id,name:i.name})))}]:[]]})))}}exports.ValidationResult=ValidationResult;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.DateTimeUtils=void 0;const luxon_1=require("luxon");class DateTimeUtils{static toTimezone(t,e){return this.switchTimezone(t,"UTC",e)}static switchTimezone(t,e,a){if(e===a)return t;return luxon_1.DateTime.fromJSDate(t,{zone:e}).setZone(a).toJSDate()}static addMinutes(t,e,a){return luxon_1.DateTime.fromJSDate(t,{zone:a}).plus({minutes:e}).toJSDate()}static addDays(t,e,a){return luxon_1.DateTime.fromJSDate(t,{zone:a}).plus({days:e}).toJSDate()}static addMonths(t,e,a){return luxon_1.DateTime.fromJSDate(t,{zone:a}).plus({months:e}).toJSDate()}static addYears(t,e,a){return luxon_1.DateTime.fromJSDate(t,{zone:a}).plus({years:e}).toJSDate()}static getDate(t,e){return luxon_1.DateTime.fromJSDate(t,{zone:e}).startOf("day").toJSDate()}static getDateFromIsoString(t){return luxon_1.DateTime.fromISO(t,{zone:"UTC"}).toJSDate()}static getDateTimeFromIsoString(t){return luxon_1.DateTime.fromISO(t,{zone:"UTC"}).toJSDate()}static getStartOfDate(t,e){const a="string"==typeof t?this.getDateFromIsoString(t):t;return luxon_1.DateTime.fromJSDate(a,{zone:e}).startOf("day").toJSDate()}static getEndOfDate(t,e){const a=this.getStartOfDate(t,e);return this.addDays(a,1,e)}static isIncluding(t,e){return t.start<=e.start&&t.finish>=e.finish}static isOverlapping(t,e){return t.start<e.finish&&t.finish>e.start}static mergeEvents(t){t.sort(((t,e)=>t.start.getTime()-e.start.getTime()));const e=[];let a=null;for(const i of t)a?new Date(a.finish)>=i.start?(a.finish=i.finish,a.eventType="merged",a.description=a.description?`${a.description}, ${a.name} merged with ${i.name}`:`${a.name} merged with ${i.name}`):(e.push(a),a=i):a=i;return a&&e.push(a),e}}exports.DateTimeUtils=DateTimeUtils;
@@ -1 +1 @@
1
- "use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,r,i){void 0===i&&(i=r);var n=Object.getOwnPropertyDescriptor(t,r);n&&!("get"in n?!t.__esModule:n.writable||n.configurable)||(n={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,i,n)}:function(e,t,r,i){void 0===i&&(i=r),e[i]=t[r]}),__exportStar=this&&this.__exportStar||function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||__createBinding(t,e,r)};Object.defineProperty(exports,"__esModule",{value:!0}),__exportStar(require("./config-helper"),exports);
1
+ "use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(e,t,r,i){void 0===i&&(i=r);var o=Object.getOwnPropertyDescriptor(t,r);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,i,o)}:function(e,t,r,i){void 0===i&&(i=r),e[i]=t[r]}),__exportStar=this&&this.__exportStar||function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||__createBinding(t,e,r)};Object.defineProperty(exports,"__esModule",{value:!0}),__exportStar(require("./config-helper"),exports),__exportStar(require("./datetime-utils"),exports);
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.sortObjectKeys=void 0;const sortObjectKeys=e=>Array.isArray(e)?e.map((e=>(0,exports.sortObjectKeys)(e))):null!==e&&"object"==typeof e?Object.keys(e).sort().reduce(((t,s)=>(t[s]=(0,exports.sortObjectKeys)(e[s]),t)),{}):e;exports.sortObjectKeys=sortObjectKeys;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skedulo/pulse-solution-services",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "A collection of services and utilities to support solution development on the Pulse platform.",
5
5
  "author": "Skedulo",
6
6
  "license": "MIT",
@@ -37,6 +37,10 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "@skedulo/function-utilities": "^0.0.6",
40
- "typescript": "~5.6.3"
40
+ "@types/luxon": "^3.4.2",
41
+ "luxon": "^3.5.0",
42
+ "typescript": "~5.6.3",
43
+ "uuid": "^11.0.5",
44
+ "winston": "^3.17.0"
41
45
  }
42
46
  }