cmp-aws-database 2.1.2-dev.7 → 2.1.2-dev.70

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 (66) hide show
  1. package/dist/config/table-names.d.ts +14 -0
  2. package/dist/config/table-names.js +15 -1
  3. package/dist/customer-user/accompaniments/accompaniments-model.d.ts +1 -0
  4. package/dist/customer-user/accompaniments/accompaniments-model.js +5 -1
  5. package/dist/customer-user/add-ons/add-ons-model.d.ts +3 -0
  6. package/dist/customer-user/add-ons/add-ons-model.js +13 -1
  7. package/dist/customer-user/browse-history/browse-history-dao.d.ts +122 -0
  8. package/dist/customer-user/browse-history/browse-history-dao.js +173 -0
  9. package/dist/customer-user/browse-history/browse-history-model.d.ts +31 -0
  10. package/dist/customer-user/browse-history/browse-history-model.js +118 -0
  11. package/dist/customer-user/cart/cart-categories-model.d.ts +6 -2
  12. package/dist/customer-user/cart/cart-categories-model.js +15 -3
  13. package/dist/customer-user/cart/cart-model.d.ts +14 -0
  14. package/dist/customer-user/cart/cart-model.js +48 -2
  15. package/dist/customer-user/category/category-dao.d.ts +29 -0
  16. package/dist/customer-user/category/category-dao.js +52 -1
  17. package/dist/customer-user/category/category-model.d.ts +1 -0
  18. package/dist/customer-user/category/category-model.js +5 -1
  19. package/dist/customer-user/cutlery/cutlery-model.d.ts +3 -0
  20. package/dist/customer-user/cutlery/cutlery-model.js +13 -1
  21. package/dist/customer-user/default-platter/default-platters-model.d.ts +2 -0
  22. package/dist/customer-user/default-platter/default-platters-model.js +9 -1
  23. package/dist/customer-user/default-platter/default_platters_items.d.ts +1 -0
  24. package/dist/customer-user/default-platter/default_platters_items.js +5 -1
  25. package/dist/customer-user/elphie/elphie-errors.d.ts +15 -0
  26. package/dist/customer-user/elphie/elphie-errors.js +31 -0
  27. package/dist/customer-user/elphie/elphie-message-dao.d.ts +51 -0
  28. package/dist/customer-user/elphie/elphie-message-dao.js +160 -0
  29. package/dist/customer-user/elphie/elphie-message-model.d.ts +25 -0
  30. package/dist/customer-user/elphie/elphie-message-model.js +78 -0
  31. package/dist/customer-user/elphie/elphie-session-dao.d.ts +46 -0
  32. package/dist/customer-user/elphie/elphie-session-dao.js +134 -0
  33. package/dist/customer-user/elphie/elphie-session-model.d.ts +26 -0
  34. package/dist/customer-user/elphie/elphie-session-model.js +55 -0
  35. package/dist/customer-user/fmpRequestCallback/fmp-request-callback-model.d.ts +1 -0
  36. package/dist/customer-user/fmpRequestCallback/fmp-request-callback-model.js +5 -1
  37. package/dist/customer-user/items/items-model.d.ts +2 -0
  38. package/dist/customer-user/items/items-model.js +9 -1
  39. package/dist/customer-user/items-bundle/items-bundle-dao.d.ts +72 -0
  40. package/dist/customer-user/items-bundle/items-bundle-dao.js +117 -0
  41. package/dist/customer-user/items-bundle/items-bundle-model.d.ts +23 -0
  42. package/dist/customer-user/items-bundle/items-bundle-model.js +62 -0
  43. package/dist/customer-user/lsq-priority-updation/lsq-priority-updation-dao.d.ts +140 -0
  44. package/dist/customer-user/lsq-priority-updation/lsq-priority-updation-dao.js +253 -0
  45. package/dist/customer-user/lsq-priority-updation/lsq-priority-updation-model.d.ts +63 -0
  46. package/dist/customer-user/lsq-priority-updation/lsq-priority-updation-model.js +135 -0
  47. package/dist/customer-user/order-module/order/order-model.d.ts +1 -0
  48. package/dist/customer-user/order-module/order/order-model.js +5 -1
  49. package/dist/customer-user/order-module/plate-order/plate-order-model.d.ts +20 -0
  50. package/dist/customer-user/order-module/plate-order/plate-order-model.js +69 -2
  51. package/dist/customer-user/order-module/tracking/tracking-model.d.ts +9 -0
  52. package/dist/customer-user/order-module/tracking/tracking-model.js +33 -2
  53. package/dist/customer-user/replace-items/replace-items-model.d.ts +1 -0
  54. package/dist/customer-user/replace-items/replace-items-model.js +5 -1
  55. package/dist/customer-user/resume-journey/resume-journey-model.d.ts +11 -0
  56. package/dist/customer-user/resume-journey/resume-journey-model.js +41 -2
  57. package/dist/customer-user/testing-session/testing-session-dao.d.ts +86 -0
  58. package/dist/customer-user/testing-session/testing-session-dao.js +149 -0
  59. package/dist/customer-user/testing-session/testing-session-model.d.ts +30 -0
  60. package/dist/customer-user/testing-session/testing-session-model.js +104 -0
  61. package/dist/patner-third-party/third-party-api-key/third-party-api-key-dao.d.ts +114 -0
  62. package/dist/patner-third-party/third-party-api-key/third-party-api-key-dao.js +225 -0
  63. package/dist/patner-third-party/third-party-api-key/third-party-api-key-model.d.ts +21 -0
  64. package/dist/patner-third-party/third-party-api-key/third-party-api-key-model.js +70 -0
  65. package/index.js +13 -1
  66. package/package.json +1 -1
@@ -46,6 +46,10 @@ __decorate([
46
46
  (0, annotations_1.attribute)(),
47
47
  __metadata("design:type", Number)
48
48
  ], DefaultPlattersItems.prototype, "itemQuantity", void 0);
49
+ __decorate([
50
+ (0, annotations_1.attribute)(),
51
+ __metadata("design:type", Number)
52
+ ], DefaultPlattersItems.prototype, "itemMaxQuantity", void 0);
49
53
  __decorate([
50
54
  (0, annotations_1.attribute)(),
51
55
  __metadata("design:type", String)
@@ -85,4 +89,4 @@ __decorate([
85
89
  exports.DefaultPlattersItems = DefaultPlattersItems = __decorate([
86
90
  (0, annotations_1.table)("DefaultPlatterItemsTable")
87
91
  ], DefaultPlattersItems);
88
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdF9wbGF0dGVyc19pdGVtcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jdXN0b21lci11c2VyL2RlZmF1bHQtcGxhdHRlci9kZWZhdWx0X3BsYXR0ZXJzX2l0ZW1zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBLHVEQUE0RTtBQUM1RSxpREFBNkM7QUFHdEMsSUFBTSxvQkFBb0IsR0FBMUIsTUFBTSxvQkFBcUIsU0FBUSxzQkFBUztDQXFDbEQsQ0FBQTtBQXJDWSxvREFBb0I7QUFFN0I7SUFEQyxJQUFBLHFCQUFPLEVBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUM7O29EQUNiO0FBR2Y7SUFGQyxJQUFBLHNCQUFRLEVBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUM7SUFDNUIsSUFBQSx1QkFBUyxFQUFDLEVBQUUsc0JBQXNCLEVBQUUsRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxDQUFDOzt1REFDaEU7QUFLbEI7SUFIQyxJQUFBLHVCQUFTLEVBQUM7UUFDUCxzQkFBc0IsRUFBRSxFQUFFLHNCQUFzQixFQUFFLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRO0tBQzlFLENBQUM7O3dEQUNpQjtBQUVuQjtJQURDLElBQUEsdUJBQVMsR0FBRTs7MERBQ1U7QUFFdEI7SUFEQyxJQUFBLHVCQUFTLEdBQUU7O3NEQUNNO0FBRWxCO0lBREMsSUFBQSx1QkFBUyxHQUFFOzsyREFDVztBQUV2QjtJQURDLElBQUEsdUJBQVMsR0FBRTs7MERBQ1U7QUFFdEI7SUFEQyxJQUFBLHVCQUFTLEdBQUU7OzhEQUNjO0FBRTFCO0lBREMsSUFBQSx1QkFBUyxHQUFFOzswREFDVTtBQUV0QjtJQURDLElBQUEsdUJBQVMsR0FBRTs7eURBQ1M7QUFFckI7SUFEQyxJQUFBLHVCQUFTLEdBQUU7O3FEQUNLO0FBRWpCO0lBREMsSUFBQSx1QkFBUyxFQUFDLEVBQUUsc0JBQXNCLEVBQUUsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUM7O3dEQUNqRTtBQUVwQjtJQURDLElBQUEsdUJBQVMsR0FBRTs7d0RBQ1U7QUFFdEI7SUFEQyxJQUFBLHVCQUFTLEdBQUU7O3FFQUNxQjtBQUVqQztJQURDLElBQUEsdUJBQVMsR0FBRTs7d0RBQ1M7QUFFckI7SUFEQyxJQUFBLHVCQUFTLEdBQUU7O3FFQUNxQjsrQkFwQ3hCLG9CQUFvQjtJQURoQyxJQUFBLG1CQUFLLEVBQUMsMEJBQTBCLENBQUM7R0FDckIsb0JBQW9CLENBcUNoQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGF0dHJpYnV0ZSwgaGFzaEtleSwgcmFuZ2VLZXksIHRhYmxlIH0gZnJvbSBcIkBub3ZhLW9kbS9hbm5vdGF0aW9uc1wiO1xuaW1wb3J0IHsgQmFzZU1vZGVsIH0gZnJvbSBcIi4uLy4uL2Jhc2UtbW9kZWxcIjtcblxuQHRhYmxlKFwiRGVmYXVsdFBsYXR0ZXJJdGVtc1RhYmxlXCIpXG5leHBvcnQgY2xhc3MgRGVmYXVsdFBsYXR0ZXJzSXRlbXMgZXh0ZW5kcyBCYXNlTW9kZWwge1xuICAgIEBoYXNoS2V5KHsgdHlwZTogXCJTdHJpbmdcIiB9KVxuICAgIGl0ZW1JZDogc3RyaW5nO1xuICAgIEByYW5nZUtleSh7IHR5cGU6IFwiU3RyaW5nXCIgfSlcbiAgICBAYXR0cmlidXRlKHsgaW5kZXhLZXlDb25maWd1cmF0aW9uczogeyBcInBsYXR0ZXJJbmRleFwiOiBcIkhBU0hcIiB9LCB0eXBlOiAnU3RyaW5nJyB9KVxuICAgIHBsYXR0ZXJJZDogc3RyaW5nO1xuXG4gICAgQGF0dHJpYnV0ZSh7XG4gICAgICAgIGluZGV4S2V5Q29uZmlndXJhdGlvbnM6IHsgXCJwbGF0dGVyQ2F0ZWdvcnlJbmRleFwiOiBcIlJBTkdFXCIgfSwgdHlwZTogJ1N0cmluZydcbiAgICB9KVxuICAgIGNhdGVnb3J5SWQ6IHN0cmluZztcbiAgICBAYXR0cmlidXRlKClcbiAgICBjYXRlZ29yeU5hbWU/OiBzdHJpbmc7XG4gICAgQGF0dHJpYnV0ZSgpXG4gICAgaXRlbU5hbWU/OiBzdHJpbmc7XG4gICAgQGF0dHJpYnV0ZSgpXG4gICAgaXRlbUJhc2VQcmljZT86IG51bWJlcjtcbiAgICBAYXR0cmlidXRlKClcbiAgICBpdGVtUXVhbnRpdHk/OiBudW1iZXI7XG4gICAgQGF0dHJpYnV0ZSgpXG4gICAgaXRlbVF1YW50aXR5VW5pdD86IHN0cmluZztcbiAgICBAYXR0cmlidXRlKClcbiAgICBpdGVtTWluUHJpY2U/OiBudW1iZXI7XG4gICAgQGF0dHJpYnV0ZSgpXG4gICAgcGxhdHRlck5hbWU/OiBzdHJpbmc7XG4gICAgQGF0dHJpYnV0ZSgpXG4gICAgcHJlbWl1bT86IHN0cmluZztcbiAgICBAYXR0cmlidXRlKHsgaW5kZXhLZXlDb25maWd1cmF0aW9uczogeyBcIml0ZW1BY3RpdmVJbmRleFwiOiBcIkhBU0hcIiB9LCB0eXBlOiAnU3RyaW5nJyB9KVxuICAgIGl0ZW1BY3RpdmU/OiBzdHJpbmc7IC8vIFYyXG4gICAgQGF0dHJpYnV0ZSgpXG4gICAgZGF5c09mV2Vlaz86IHN0cmluZ1tdO1xuICAgIEBhdHRyaWJ1dGUoKVxuICAgIGZyZWVBY2NvbXBhbmltZW50c0xpbWl0PzogbnVtYmVyOyAvLyBGb3IgYWNjb21wbGltZW50c1RhYmxlIFZhbHVlIENoZWNrXG4gICAgQGF0dHJpYnV0ZSgpXG4gICAgaXNCYXNlSXRlbT86IGJvb2xlYW47IC8vIEZvciBwbGF0dGVySW1hZ2UgVmFsdWUgQ2hlY2tcbiAgICBAYXR0cmlidXRlKClcbiAgICBpdGVtRGlzY291bnRGYWN0b3JWYWx1ZT86IG51bWJlcjsgLy8gVjJcbn0iXX0=
92
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdF9wbGF0dGVyc19pdGVtcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jdXN0b21lci11c2VyL2RlZmF1bHQtcGxhdHRlci9kZWZhdWx0X3BsYXR0ZXJzX2l0ZW1zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBLHVEQUE0RTtBQUM1RSxpREFBNkM7QUFHdEMsSUFBTSxvQkFBb0IsR0FBMUIsTUFBTSxvQkFBcUIsU0FBUSxzQkFBUztDQXVDbEQsQ0FBQTtBQXZDWSxvREFBb0I7QUFFN0I7SUFEQyxJQUFBLHFCQUFPLEVBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUM7O29EQUNiO0FBR2Y7SUFGQyxJQUFBLHNCQUFRLEVBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUM7SUFDNUIsSUFBQSx1QkFBUyxFQUFDLEVBQUUsc0JBQXNCLEVBQUUsRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxDQUFDOzt1REFDaEU7QUFLbEI7SUFIQyxJQUFBLHVCQUFTLEVBQUM7UUFDUCxzQkFBc0IsRUFBRSxFQUFFLHNCQUFzQixFQUFFLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRO0tBQzlFLENBQUM7O3dEQUNpQjtBQUVuQjtJQURDLElBQUEsdUJBQVMsR0FBRTs7MERBQ1U7QUFFdEI7SUFEQyxJQUFBLHVCQUFTLEdBQUU7O3NEQUNNO0FBRWxCO0lBREMsSUFBQSx1QkFBUyxHQUFFOzsyREFDVztBQUV2QjtJQURDLElBQUEsdUJBQVMsR0FBRTs7MERBQ1U7QUFFdEI7SUFEQyxJQUFBLHVCQUFTLEdBQUU7OzZEQUNhO0FBRXpCO0lBREMsSUFBQSx1QkFBUyxHQUFFOzs4REFDYztBQUUxQjtJQURDLElBQUEsdUJBQVMsR0FBRTs7MERBQ1U7QUFFdEI7SUFEQyxJQUFBLHVCQUFTLEdBQUU7O3lEQUNTO0FBRXJCO0lBREMsSUFBQSx1QkFBUyxHQUFFOztxREFDSztBQUVqQjtJQURDLElBQUEsdUJBQVMsRUFBQyxFQUFFLHNCQUFzQixFQUFFLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxDQUFDOzt3REFDakU7QUFFcEI7SUFEQyxJQUFBLHVCQUFTLEdBQUU7O3dEQUNVO0FBRXRCO0lBREMsSUFBQSx1QkFBUyxHQUFFOztxRUFDcUI7QUFFakM7SUFEQyxJQUFBLHVCQUFTLEdBQUU7O3dEQUNTO0FBRXJCO0lBREMsSUFBQSx1QkFBUyxHQUFFOztxRUFDcUI7K0JBdEN4QixvQkFBb0I7SUFEaEMsSUFBQSxtQkFBSyxFQUFDLDBCQUEwQixDQUFDO0dBQ3JCLG9CQUFvQixDQXVDaEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBhdHRyaWJ1dGUsIGhhc2hLZXksIHJhbmdlS2V5LCB0YWJsZSB9IGZyb20gXCJAbm92YS1vZG0vYW5ub3RhdGlvbnNcIjtcbmltcG9ydCB7IEJhc2VNb2RlbCB9IGZyb20gXCIuLi8uLi9iYXNlLW1vZGVsXCI7XG5cbkB0YWJsZShcIkRlZmF1bHRQbGF0dGVySXRlbXNUYWJsZVwiKVxuZXhwb3J0IGNsYXNzIERlZmF1bHRQbGF0dGVyc0l0ZW1zIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgICBAaGFzaEtleSh7IHR5cGU6IFwiU3RyaW5nXCIgfSlcbiAgICBpdGVtSWQ6IHN0cmluZztcbiAgICBAcmFuZ2VLZXkoeyB0eXBlOiBcIlN0cmluZ1wiIH0pXG4gICAgQGF0dHJpYnV0ZSh7IGluZGV4S2V5Q29uZmlndXJhdGlvbnM6IHsgXCJwbGF0dGVySW5kZXhcIjogXCJIQVNIXCIgfSwgdHlwZTogJ1N0cmluZycgfSlcbiAgICBwbGF0dGVySWQ6IHN0cmluZztcblxuICAgIEBhdHRyaWJ1dGUoe1xuICAgICAgICBpbmRleEtleUNvbmZpZ3VyYXRpb25zOiB7IFwicGxhdHRlckNhdGVnb3J5SW5kZXhcIjogXCJSQU5HRVwiIH0sIHR5cGU6ICdTdHJpbmcnXG4gICAgfSlcbiAgICBjYXRlZ29yeUlkOiBzdHJpbmc7XG4gICAgQGF0dHJpYnV0ZSgpXG4gICAgY2F0ZWdvcnlOYW1lPzogc3RyaW5nO1xuICAgIEBhdHRyaWJ1dGUoKVxuICAgIGl0ZW1OYW1lPzogc3RyaW5nO1xuICAgIEBhdHRyaWJ1dGUoKVxuICAgIGl0ZW1CYXNlUHJpY2U/OiBudW1iZXI7XG4gICAgQGF0dHJpYnV0ZSgpXG4gICAgaXRlbVF1YW50aXR5PzogbnVtYmVyO1xuICAgIEBhdHRyaWJ1dGUoKVxuICAgIGl0ZW1NYXhRdWFudGl0eT86IG51bWJlcjtcbiAgICBAYXR0cmlidXRlKClcbiAgICBpdGVtUXVhbnRpdHlVbml0Pzogc3RyaW5nO1xuICAgIEBhdHRyaWJ1dGUoKVxuICAgIGl0ZW1NaW5QcmljZT86IG51bWJlcjtcbiAgICBAYXR0cmlidXRlKClcbiAgICBwbGF0dGVyTmFtZT86IHN0cmluZztcbiAgICBAYXR0cmlidXRlKClcbiAgICBwcmVtaXVtPzogc3RyaW5nO1xuICAgIEBhdHRyaWJ1dGUoeyBpbmRleEtleUNvbmZpZ3VyYXRpb25zOiB7IFwiaXRlbUFjdGl2ZUluZGV4XCI6IFwiSEFTSFwiIH0sIHR5cGU6ICdTdHJpbmcnIH0pXG4gICAgaXRlbUFjdGl2ZT86IHN0cmluZzsgLy8gVjJcbiAgICBAYXR0cmlidXRlKClcbiAgICBkYXlzT2ZXZWVrPzogc3RyaW5nW107XG4gICAgQGF0dHJpYnV0ZSgpXG4gICAgZnJlZUFjY29tcGFuaW1lbnRzTGltaXQ/OiBudW1iZXI7IC8vIEZvciBhY2NvbXBsaW1lbnRzVGFibGUgVmFsdWUgQ2hlY2tcbiAgICBAYXR0cmlidXRlKClcbiAgICBpc0Jhc2VJdGVtPzogYm9vbGVhbjsgLy8gRm9yIHBsYXR0ZXJJbWFnZSBWYWx1ZSBDaGVja1xuICAgIEBhdHRyaWJ1dGUoKVxuICAgIGl0ZW1EaXNjb3VudEZhY3RvclZhbHVlPzogbnVtYmVyOyAvLyBWMlxufSJdfQ==
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Typed errors for Elphie DynamoDB access — callers should not see raw Dynamoose/AWS errors.
3
+ */
4
+ export declare class SessionNotFoundError extends Error {
5
+ readonly statusCode = 404;
6
+ constructor(elphieSessionId: string);
7
+ }
8
+ export declare class ConversationNotFoundError extends Error {
9
+ readonly statusCode = 404;
10
+ constructor(conversationId: string);
11
+ }
12
+ export declare class ElphieValidationError extends Error {
13
+ readonly statusCode = 400;
14
+ constructor(message: string);
15
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ /**
3
+ * Typed errors for Elphie DynamoDB access — callers should not see raw Dynamoose/AWS errors.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ElphieValidationError = exports.ConversationNotFoundError = exports.SessionNotFoundError = void 0;
7
+ class SessionNotFoundError extends Error {
8
+ constructor(elphieSessionId) {
9
+ super(`Elphie session not found: ${elphieSessionId}`);
10
+ this.statusCode = 404;
11
+ this.name = "SessionNotFoundError";
12
+ }
13
+ }
14
+ exports.SessionNotFoundError = SessionNotFoundError;
15
+ class ConversationNotFoundError extends Error {
16
+ constructor(conversationId) {
17
+ super(`Elphie conversation not found: ${conversationId}`);
18
+ this.statusCode = 404;
19
+ this.name = "ConversationNotFoundError";
20
+ }
21
+ }
22
+ exports.ConversationNotFoundError = ConversationNotFoundError;
23
+ class ElphieValidationError extends Error {
24
+ constructor(message) {
25
+ super(message);
26
+ this.statusCode = 400;
27
+ this.name = "ElphieValidationError";
28
+ }
29
+ }
30
+ exports.ElphieValidationError = ElphieValidationError;
31
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxwaGllLWVycm9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jdXN0b21lci11c2VyL2VscGhpZS9lbHBoaWUtZXJyb3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7R0FFRzs7O0FBRUgsTUFBYSxvQkFBcUIsU0FBUSxLQUFLO0lBRzNDLFlBQVksZUFBdUI7UUFDL0IsS0FBSyxDQUFDLDZCQUE2QixlQUFlLEVBQUUsQ0FBQyxDQUFDO1FBSGpELGVBQVUsR0FBRyxHQUFHLENBQUM7UUFJdEIsSUFBSSxDQUFDLElBQUksR0FBRyxzQkFBc0IsQ0FBQztJQUN2QyxDQUFDO0NBQ0o7QUFQRCxvREFPQztBQUVELE1BQWEseUJBQTBCLFNBQVEsS0FBSztJQUdoRCxZQUFZLGNBQXNCO1FBQzlCLEtBQUssQ0FBQyxrQ0FBa0MsY0FBYyxFQUFFLENBQUMsQ0FBQztRQUhyRCxlQUFVLEdBQUcsR0FBRyxDQUFDO1FBSXRCLElBQUksQ0FBQyxJQUFJLEdBQUcsMkJBQTJCLENBQUM7SUFDNUMsQ0FBQztDQUNKO0FBUEQsOERBT0M7QUFFRCxNQUFhLHFCQUFzQixTQUFRLEtBQUs7SUFHNUMsWUFBWSxPQUFlO1FBQ3ZCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUhWLGVBQVUsR0FBRyxHQUFHLENBQUM7UUFJdEIsSUFBSSxDQUFDLElBQUksR0FBRyx1QkFBdUIsQ0FBQztJQUN4QyxDQUFDO0NBQ0o7QUFQRCxzREFPQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVHlwZWQgZXJyb3JzIGZvciBFbHBoaWUgRHluYW1vREIgYWNjZXNzIOKAlCBjYWxsZXJzIHNob3VsZCBub3Qgc2VlIHJhdyBEeW5hbW9vc2UvQVdTIGVycm9ycy5cbiAqL1xuXG5leHBvcnQgY2xhc3MgU2Vzc2lvbk5vdEZvdW5kRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gICAgcmVhZG9ubHkgc3RhdHVzQ29kZSA9IDQwNDtcblxuICAgIGNvbnN0cnVjdG9yKGVscGhpZVNlc3Npb25JZDogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGBFbHBoaWUgc2Vzc2lvbiBub3QgZm91bmQ6ICR7ZWxwaGllU2Vzc2lvbklkfWApO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNlc3Npb25Ob3RGb3VuZEVycm9yXCI7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgQ29udmVyc2F0aW9uTm90Rm91bmRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICByZWFkb25seSBzdGF0dXNDb2RlID0gNDA0O1xuXG4gICAgY29uc3RydWN0b3IoY29udmVyc2F0aW9uSWQ6IHN0cmluZykge1xuICAgICAgICBzdXBlcihgRWxwaGllIGNvbnZlcnNhdGlvbiBub3QgZm91bmQ6ICR7Y29udmVyc2F0aW9uSWR9YCk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQ29udmVyc2F0aW9uTm90Rm91bmRFcnJvclwiO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEVscGhpZVZhbGlkYXRpb25FcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICByZWFkb25seSBzdGF0dXNDb2RlID0gNDAwO1xuXG4gICAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkVscGhpZVZhbGlkYXRpb25FcnJvclwiO1xuICAgIH1cbn1cbiJdfQ==
@@ -0,0 +1,51 @@
1
+ import { DynamoKey } from "../../base-dynamoose-dao";
2
+ import { CreateElphieConversationInput, ElphieMessage, ElphieMessageTurn } from "./elphie-message-model";
3
+ type ListResult = {
4
+ items: ElphieMessage[];
5
+ lastKey?: DynamoKey;
6
+ };
7
+ /**
8
+ * Service/DAO for `elphie_messages`.
9
+ *
10
+ * HASH: `conversation_id`.
11
+ * Turn append uses Dynamoose `$APPEND` (atomic) — never full-item read-modify-write.
12
+ */
13
+ declare class ElphieMessageService {
14
+ /**
15
+ * Creates a conversation with the first turn already in `content`.
16
+ *
17
+ * @example
18
+ * await elphieMessageService.createConversation({
19
+ * conversation_id: "conv-1",
20
+ * user_id: "user-1",
21
+ * elphieSessionId: "session-uuid",
22
+ * firstTurn: { role: "user", text: "Hi", timestamp: new Date().toISOString() }
23
+ * });
24
+ */
25
+ createConversation: (input: CreateElphieConversationInput) => Promise<ElphieMessage>;
26
+ /**
27
+ * Atomically appends one turn to `content` and refreshes `updated_at`.
28
+ * Uses `$APPEND` so concurrent turns cannot lose updates.
29
+ */
30
+ appendTurn: (conversation_id: string, turn: ElphieMessageTurn) => Promise<ElphieMessage>;
31
+ /**
32
+ * Fetches one conversation by `conversation_id`.
33
+ * Throws `ConversationNotFoundError` when missing.
34
+ */
35
+ getConversation: (conversation_id: string) => Promise<ElphieMessage>;
36
+ /**
37
+ * Lists conversations for a user via GSI `user_id-index`.
38
+ * Newest-first order is applied in memory on `updated_at` (not a GSI range key).
39
+ */
40
+ listConversationsForUser: (user_id: string, { limit, lastKey }?: {
41
+ limit?: number;
42
+ lastKey?: DynamoKey;
43
+ }) => Promise<ListResult>;
44
+ /**
45
+ * Lists conversations linked to a session via GSI `elphieSessionId-index`.
46
+ */
47
+ listConversationsForSession: (elphieSessionId: string) => Promise<ElphieMessage[]>;
48
+ private assertValidTurn;
49
+ }
50
+ export declare const elphieMessageService: ElphieMessageService;
51
+ export {};
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.elphieMessageService = void 0;
7
+ const dynamoose_1 = __importDefault(require("dynamoose"));
8
+ const elphie_errors_1 = require("./elphie-errors");
9
+ const elphie_message_model_1 = require("./elphie-message-model");
10
+ const nowIso = () => new Date().toISOString();
11
+ const isValidRole = (role) => role === elphie_message_model_1.ELPHIE_MESSAGE_ROLE.USER || role === elphie_message_model_1.ELPHIE_MESSAGE_ROLE.ELPHIE;
12
+ /**
13
+ * Service/DAO for `elphie_messages`.
14
+ *
15
+ * HASH: `conversation_id`.
16
+ * Turn append uses Dynamoose `$APPEND` (atomic) — never full-item read-modify-write.
17
+ */
18
+ class ElphieMessageService {
19
+ constructor() {
20
+ /**
21
+ * Creates a conversation with the first turn already in `content`.
22
+ *
23
+ * @example
24
+ * await elphieMessageService.createConversation({
25
+ * conversation_id: "conv-1",
26
+ * user_id: "user-1",
27
+ * elphieSessionId: "session-uuid",
28
+ * firstTurn: { role: "user", text: "Hi", timestamp: new Date().toISOString() }
29
+ * });
30
+ */
31
+ this.createConversation = async (input) => {
32
+ this.assertValidTurn(input.firstTurn);
33
+ try {
34
+ const created = await elphie_message_model_1.ElphieMessageModel.create({
35
+ conversation_id: input.conversation_id,
36
+ user_id: input.user_id,
37
+ elphieSessionId: input.elphieSessionId,
38
+ content: [input.firstTurn],
39
+ updated_at: nowIso()
40
+ });
41
+ return created;
42
+ }
43
+ catch (error) {
44
+ throw wrapUnexpected("createConversation", error);
45
+ }
46
+ };
47
+ /**
48
+ * Atomically appends one turn to `content` and refreshes `updated_at`.
49
+ * Uses `$APPEND` so concurrent turns cannot lose updates.
50
+ */
51
+ this.appendTurn = async (conversation_id, turn) => {
52
+ this.assertValidTurn(turn);
53
+ try {
54
+ // Dynamoose list append operator — not expressible as Partial<ElphieMessage>.
55
+ const updateObj = {
56
+ content: { $APPEND: [turn] },
57
+ updated_at: nowIso()
58
+ };
59
+ const updated = await elphie_message_model_1.ElphieMessageModel.update({ conversation_id }, updateObj, {
60
+ condition: new dynamoose_1.default.Condition().attribute("conversation_id").exists()
61
+ });
62
+ return updated;
63
+ }
64
+ catch (error) {
65
+ if (isNotFoundError(error) || isConditionalCheckFailed(error)) {
66
+ throw new elphie_errors_1.ConversationNotFoundError(conversation_id);
67
+ }
68
+ throw wrapUnexpected("appendTurn", error);
69
+ }
70
+ };
71
+ /**
72
+ * Fetches one conversation by `conversation_id`.
73
+ * Throws `ConversationNotFoundError` when missing.
74
+ */
75
+ this.getConversation = async (conversation_id) => {
76
+ try {
77
+ const conversation = await elphie_message_model_1.ElphieMessageModel.get(conversation_id);
78
+ if (!conversation) {
79
+ throw new elphie_errors_1.ConversationNotFoundError(conversation_id);
80
+ }
81
+ return conversation;
82
+ }
83
+ catch (error) {
84
+ if (error instanceof elphie_errors_1.ConversationNotFoundError) {
85
+ throw error;
86
+ }
87
+ if (isNotFoundError(error)) {
88
+ throw new elphie_errors_1.ConversationNotFoundError(conversation_id);
89
+ }
90
+ throw wrapUnexpected("getConversation", error);
91
+ }
92
+ };
93
+ /**
94
+ * Lists conversations for a user via GSI `user_id-index`.
95
+ * Newest-first order is applied in memory on `updated_at` (not a GSI range key).
96
+ */
97
+ this.listConversationsForUser = async (user_id, { limit, lastKey } = {}) => {
98
+ try {
99
+ let queryBuilder = elphie_message_model_1.ElphieMessageModel.query("user_id")
100
+ .eq(user_id)
101
+ .using("user_id-index");
102
+ if (lastKey) {
103
+ queryBuilder = queryBuilder.startAt(lastKey);
104
+ }
105
+ if (typeof limit === "number") {
106
+ queryBuilder = queryBuilder.limit(limit);
107
+ }
108
+ const queryResult = await queryBuilder.exec();
109
+ const items = [...queryResult].sort((a, b) => (b.updated_at ?? "").localeCompare(a.updated_at ?? ""));
110
+ return {
111
+ items,
112
+ lastKey: queryResult.lastKey
113
+ };
114
+ }
115
+ catch (error) {
116
+ throw wrapUnexpected("listConversationsForUser", error);
117
+ }
118
+ };
119
+ /**
120
+ * Lists conversations linked to a session via GSI `elphieSessionId-index`.
121
+ */
122
+ this.listConversationsForSession = async (elphieSessionId) => {
123
+ try {
124
+ const queryResult = await elphie_message_model_1.ElphieMessageModel.query("elphieSessionId")
125
+ .eq(elphieSessionId)
126
+ .using("elphieSessionId-index")
127
+ .exec();
128
+ return queryResult;
129
+ }
130
+ catch (error) {
131
+ throw wrapUnexpected("listConversationsForSession", error);
132
+ }
133
+ };
134
+ this.assertValidTurn = (turn) => {
135
+ if (!turn || typeof turn.text !== "string" || turn.text.length === 0) {
136
+ throw new elphie_errors_1.ElphieValidationError("turn.text is required");
137
+ }
138
+ if (!isValidRole(turn.role)) {
139
+ throw new elphie_errors_1.ElphieValidationError(`Invalid turn.role "${turn.role}". Expected "user" | "elphie".`);
140
+ }
141
+ if (!turn.timestamp) {
142
+ throw new elphie_errors_1.ElphieValidationError("turn.timestamp is required");
143
+ }
144
+ };
145
+ }
146
+ }
147
+ const isNotFoundError = (error) => {
148
+ const name = error?.name;
149
+ return name === "ItemNotFoundException" || name === "ItemNotFoundError";
150
+ };
151
+ const isConditionalCheckFailed = (error) => {
152
+ const name = error?.name;
153
+ return name === "ConditionalCheckFailedException";
154
+ };
155
+ const wrapUnexpected = (operation, error) => {
156
+ const message = error instanceof Error ? error.message : String(error);
157
+ return new Error(`ElphieMessageService.${operation} failed: ${message}`);
158
+ };
159
+ exports.elphieMessageService = new ElphieMessageService();
160
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxwaGllLW1lc3NhZ2UtZGFvLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2N1c3RvbWVyLXVzZXIvZWxwaGllL2VscGhpZS1tZXNzYWdlLWRhby50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSwwREFBa0M7QUFFbEMsbURBQW1GO0FBQ25GLGlFQU9nQztBQU9oQyxNQUFNLE1BQU0sR0FBRyxHQUFXLEVBQUUsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDO0FBRXRELE1BQU0sV0FBVyxHQUFHLENBQUMsSUFBWSxFQUE2QixFQUFFLENBQzVELElBQUksS0FBSywwQ0FBbUIsQ0FBQyxJQUFJLElBQUksSUFBSSxLQUFLLDBDQUFtQixDQUFDLE1BQU0sQ0FBQztBQUU3RTs7Ozs7R0FLRztBQUNILE1BQU0sb0JBQW9CO0lBQTFCO1FBQ0k7Ozs7Ozs7Ozs7V0FVRztRQUNILHVCQUFrQixHQUFHLEtBQUssRUFBRSxLQUFvQyxFQUEwQixFQUFFO1lBQ3hGLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBRXRDLElBQUksQ0FBQztnQkFDRCxNQUFNLE9BQU8sR0FBRyxNQUFNLHlDQUFrQixDQUFDLE1BQU0sQ0FBQztvQkFDNUMsZUFBZSxFQUFFLEtBQUssQ0FBQyxlQUFlO29CQUN0QyxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU87b0JBQ3RCLGVBQWUsRUFBRSxLQUFLLENBQUMsZUFBZTtvQkFDdEMsT0FBTyxFQUFFLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztvQkFDMUIsVUFBVSxFQUFFLE1BQU0sRUFBRTtpQkFDdkIsQ0FBQyxDQUFDO2dCQUNILE9BQU8sT0FBd0IsQ0FBQztZQUNwQyxDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDYixNQUFNLGNBQWMsQ0FBQyxvQkFBb0IsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN0RCxDQUFDO1FBQ0wsQ0FBQyxDQUFDO1FBRUY7OztXQUdHO1FBQ0gsZUFBVSxHQUFHLEtBQUssRUFBRSxlQUF1QixFQUFFLElBQXVCLEVBQTBCLEVBQUU7WUFDNUYsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUUzQixJQUFJLENBQUM7Z0JBQ0QsOEVBQThFO2dCQUM5RSxNQUFNLFNBQVMsR0FBRztvQkFDZCxPQUFPLEVBQUUsRUFBRSxPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRTtvQkFDNUIsVUFBVSxFQUFFLE1BQU0sRUFBRTtpQkFDdkIsQ0FBQztnQkFDRixNQUFNLE9BQU8sR0FBRyxNQUFNLHlDQUFrQixDQUFDLE1BQU0sQ0FDM0MsRUFBRSxlQUFlLEVBQUUsRUFDbkIsU0FBdUUsRUFDdkU7b0JBQ0ksU0FBUyxFQUFFLElBQUksbUJBQVMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxTQUFTLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxNQUFNLEVBQUU7aUJBQzdFLENBQ0osQ0FBQztnQkFDRixPQUFPLE9BQW1DLENBQUM7WUFDL0MsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2IsSUFBSSxlQUFlLENBQUMsS0FBSyxDQUFDLElBQUksd0JBQXdCLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztvQkFDNUQsTUFBTSxJQUFJLHlDQUF5QixDQUFDLGVBQWUsQ0FBQyxDQUFDO2dCQUN6RCxDQUFDO2dCQUNELE1BQU0sY0FBYyxDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsQ0FBQztZQUM5QyxDQUFDO1FBQ0wsQ0FBQyxDQUFDO1FBRUY7OztXQUdHO1FBQ0gsb0JBQWUsR0FBRyxLQUFLLEVBQUUsZUFBdUIsRUFBMEIsRUFBRTtZQUN4RSxJQUFJLENBQUM7Z0JBQ0QsTUFBTSxZQUFZLEdBQUcsTUFBTSx5Q0FBa0IsQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLENBQUM7Z0JBQ25FLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztvQkFDaEIsTUFBTSxJQUFJLHlDQUF5QixDQUFDLGVBQWUsQ0FBQyxDQUFDO2dCQUN6RCxDQUFDO2dCQUNELE9BQU8sWUFBNkIsQ0FBQztZQUN6QyxDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDYixJQUFJLEtBQUssWUFBWSx5Q0FBeUIsRUFBRSxDQUFDO29CQUM3QyxNQUFNLEtBQUssQ0FBQztnQkFDaEIsQ0FBQztnQkFDRCxJQUFJLGVBQWUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO29CQUN6QixNQUFNLElBQUkseUNBQXlCLENBQUMsZUFBZSxDQUFDLENBQUM7Z0JBQ3pELENBQUM7Z0JBQ0QsTUFBTSxjQUFjLENBQUMsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDbkQsQ0FBQztRQUNMLENBQUMsQ0FBQztRQUVGOzs7V0FHRztRQUNILDZCQUF3QixHQUFHLEtBQUssRUFDNUIsT0FBZSxFQUNmLEVBQUUsS0FBSyxFQUFFLE9BQU8sS0FBOEMsRUFBRSxFQUM3QyxFQUFFO1lBQ3JCLElBQUksQ0FBQztnQkFDRCxJQUFJLFlBQVksR0FBRyx5Q0FBa0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO3FCQUNqRCxFQUFFLENBQUMsT0FBTyxDQUFDO3FCQUNYLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQztnQkFFNUIsSUFBSSxPQUFPLEVBQUUsQ0FBQztvQkFDVixZQUFZLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDakQsQ0FBQztnQkFDRCxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRSxDQUFDO29CQUM1QixZQUFZLEdBQUcsWUFBWSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDN0MsQ0FBQztnQkFFRCxNQUFNLFdBQVcsR0FBRyxNQUFNLFlBQVksQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDOUMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxHQUFJLFdBQTBDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FDekUsQ0FBQyxDQUFDLENBQUMsVUFBVSxJQUFJLEVBQUUsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsVUFBVSxJQUFJLEVBQUUsQ0FBQyxDQUN6RCxDQUFDO2dCQUNGLE9BQU87b0JBQ0gsS0FBSztvQkFDTCxPQUFPLEVBQUUsV0FBVyxDQUFDLE9BQWdDO2lCQUN4RCxDQUFDO1lBQ04sQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2IsTUFBTSxjQUFjLENBQUMsMEJBQTBCLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDNUQsQ0FBQztRQUNMLENBQUMsQ0FBQztRQUVGOztXQUVHO1FBQ0gsZ0NBQTJCLEdBQUcsS0FBSyxFQUFFLGVBQXVCLEVBQTRCLEVBQUU7WUFDdEYsSUFBSSxDQUFDO2dCQUNELE1BQU0sV0FBVyxHQUFHLE1BQU0seUNBQWtCLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDO3FCQUNoRSxFQUFFLENBQUMsZUFBZSxDQUFDO3FCQUNuQixLQUFLLENBQUMsdUJBQXVCLENBQUM7cUJBQzlCLElBQUksRUFBRSxDQUFDO2dCQUNaLE9BQU8sV0FBeUMsQ0FBQztZQUNyRCxDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDYixNQUFNLGNBQWMsQ0FBQyw2QkFBNkIsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMvRCxDQUFDO1FBQ0wsQ0FBQyxDQUFDO1FBRU0sb0JBQWUsR0FBRyxDQUFDLElBQXVCLEVBQVEsRUFBRTtZQUN4RCxJQUFJLENBQUMsSUFBSSxJQUFJLE9BQU8sSUFBSSxDQUFDLElBQUksS0FBSyxRQUFRLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ25FLE1BQU0sSUFBSSxxQ0FBcUIsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1lBQzdELENBQUM7WUFDRCxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUMxQixNQUFNLElBQUkscUNBQXFCLENBQzNCLHNCQUFzQixJQUFJLENBQUMsSUFBSSxnQ0FBZ0MsQ0FDbEUsQ0FBQztZQUNOLENBQUM7WUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNsQixNQUFNLElBQUkscUNBQXFCLENBQUMsNEJBQTRCLENBQUMsQ0FBQztZQUNsRSxDQUFDO1FBQ0wsQ0FBQyxDQUFDO0lBQ04sQ0FBQztDQUFBO0FBRUQsTUFBTSxlQUFlLEdBQUcsQ0FBQyxLQUFjLEVBQVcsRUFBRTtJQUNoRCxNQUFNLElBQUksR0FBSSxLQUFrQyxFQUFFLElBQUksQ0FBQztJQUN2RCxPQUFPLElBQUksS0FBSyx1QkFBdUIsSUFBSSxJQUFJLEtBQUssbUJBQW1CLENBQUM7QUFDNUUsQ0FBQyxDQUFDO0FBRUYsTUFBTSx3QkFBd0IsR0FBRyxDQUFDLEtBQWMsRUFBVyxFQUFFO0lBQ3pELE1BQU0sSUFBSSxHQUFJLEtBQWtDLEVBQUUsSUFBSSxDQUFDO0lBQ3ZELE9BQU8sSUFBSSxLQUFLLGlDQUFpQyxDQUFDO0FBQ3RELENBQUMsQ0FBQztBQUVGLE1BQU0sY0FBYyxHQUFHLENBQUMsU0FBaUIsRUFBRSxLQUFjLEVBQVMsRUFBRTtJQUNoRSxNQUFNLE9BQU8sR0FBRyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdkUsT0FBTyxJQUFJLEtBQUssQ0FBQyx3QkFBd0IsU0FBUyxZQUFZLE9BQU8sRUFBRSxDQUFDLENBQUM7QUFDN0UsQ0FBQyxDQUFDO0FBRVcsUUFBQSxvQkFBb0IsR0FBRyxJQUFJLG9CQUFvQixFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZHluYW1vb3NlIGZyb20gXCJkeW5hbW9vc2VcIjtcbmltcG9ydCB7IER5bmFtb0tleSB9IGZyb20gXCIuLi8uLi9iYXNlLWR5bmFtb29zZS1kYW9cIjtcbmltcG9ydCB7IENvbnZlcnNhdGlvbk5vdEZvdW5kRXJyb3IsIEVscGhpZVZhbGlkYXRpb25FcnJvciB9IGZyb20gXCIuL2VscGhpZS1lcnJvcnNcIjtcbmltcG9ydCB7XG4gICAgQ3JlYXRlRWxwaGllQ29udmVyc2F0aW9uSW5wdXQsXG4gICAgRUxQSElFX01FU1NBR0VfUk9MRSxcbiAgICBFbHBoaWVNZXNzYWdlLFxuICAgIEVscGhpZU1lc3NhZ2VNb2RlbCxcbiAgICBFbHBoaWVNZXNzYWdlUm9sZSxcbiAgICBFbHBoaWVNZXNzYWdlVHVyblxufSBmcm9tIFwiLi9lbHBoaWUtbWVzc2FnZS1tb2RlbFwiO1xuXG50eXBlIExpc3RSZXN1bHQgPSB7XG4gICAgaXRlbXM6IEVscGhpZU1lc3NhZ2VbXTtcbiAgICBsYXN0S2V5PzogRHluYW1vS2V5O1xufTtcblxuY29uc3Qgbm93SXNvID0gKCk6IHN0cmluZyA9PiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG5cbmNvbnN0IGlzVmFsaWRSb2xlID0gKHJvbGU6IHN0cmluZyk6IHJvbGUgaXMgRWxwaGllTWVzc2FnZVJvbGUgPT5cbiAgICByb2xlID09PSBFTFBISUVfTUVTU0FHRV9ST0xFLlVTRVIgfHwgcm9sZSA9PT0gRUxQSElFX01FU1NBR0VfUk9MRS5FTFBISUU7XG5cbi8qKlxuICogU2VydmljZS9EQU8gZm9yIGBlbHBoaWVfbWVzc2FnZXNgLlxuICpcbiAqIEhBU0g6IGBjb252ZXJzYXRpb25faWRgLlxuICogVHVybiBhcHBlbmQgdXNlcyBEeW5hbW9vc2UgYCRBUFBFTkRgIChhdG9taWMpIOKAlCBuZXZlciBmdWxsLWl0ZW0gcmVhZC1tb2RpZnktd3JpdGUuXG4gKi9cbmNsYXNzIEVscGhpZU1lc3NhZ2VTZXJ2aWNlIHtcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgY29udmVyc2F0aW9uIHdpdGggdGhlIGZpcnN0IHR1cm4gYWxyZWFkeSBpbiBgY29udGVudGAuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGF3YWl0IGVscGhpZU1lc3NhZ2VTZXJ2aWNlLmNyZWF0ZUNvbnZlcnNhdGlvbih7XG4gICAgICogICAgIGNvbnZlcnNhdGlvbl9pZDogXCJjb252LTFcIixcbiAgICAgKiAgICAgdXNlcl9pZDogXCJ1c2VyLTFcIixcbiAgICAgKiAgICAgZWxwaGllU2Vzc2lvbklkOiBcInNlc3Npb24tdXVpZFwiLFxuICAgICAqICAgICBmaXJzdFR1cm46IHsgcm9sZTogXCJ1c2VyXCIsIHRleHQ6IFwiSGlcIiwgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkgfVxuICAgICAqIH0pO1xuICAgICAqL1xuICAgIGNyZWF0ZUNvbnZlcnNhdGlvbiA9IGFzeW5jIChpbnB1dDogQ3JlYXRlRWxwaGllQ29udmVyc2F0aW9uSW5wdXQpOiBQcm9taXNlPEVscGhpZU1lc3NhZ2U+ID0+IHtcbiAgICAgICAgdGhpcy5hc3NlcnRWYWxpZFR1cm4oaW5wdXQuZmlyc3RUdXJuKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgY3JlYXRlZCA9IGF3YWl0IEVscGhpZU1lc3NhZ2VNb2RlbC5jcmVhdGUoe1xuICAgICAgICAgICAgICAgIGNvbnZlcnNhdGlvbl9pZDogaW5wdXQuY29udmVyc2F0aW9uX2lkLFxuICAgICAgICAgICAgICAgIHVzZXJfaWQ6IGlucHV0LnVzZXJfaWQsXG4gICAgICAgICAgICAgICAgZWxwaGllU2Vzc2lvbklkOiBpbnB1dC5lbHBoaWVTZXNzaW9uSWQsXG4gICAgICAgICAgICAgICAgY29udGVudDogW2lucHV0LmZpcnN0VHVybl0sXG4gICAgICAgICAgICAgICAgdXBkYXRlZF9hdDogbm93SXNvKClcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZWQgYXMgRWxwaGllTWVzc2FnZTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRocm93IHdyYXBVbmV4cGVjdGVkKFwiY3JlYXRlQ29udmVyc2F0aW9uXCIsIGVycm9yKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBdG9taWNhbGx5IGFwcGVuZHMgb25lIHR1cm4gdG8gYGNvbnRlbnRgIGFuZCByZWZyZXNoZXMgYHVwZGF0ZWRfYXRgLlxuICAgICAqIFVzZXMgYCRBUFBFTkRgIHNvIGNvbmN1cnJlbnQgdHVybnMgY2Fubm90IGxvc2UgdXBkYXRlcy5cbiAgICAgKi9cbiAgICBhcHBlbmRUdXJuID0gYXN5bmMgKGNvbnZlcnNhdGlvbl9pZDogc3RyaW5nLCB0dXJuOiBFbHBoaWVNZXNzYWdlVHVybik6IFByb21pc2U8RWxwaGllTWVzc2FnZT4gPT4ge1xuICAgICAgICB0aGlzLmFzc2VydFZhbGlkVHVybih0dXJuKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gRHluYW1vb3NlIGxpc3QgYXBwZW5kIG9wZXJhdG9yIOKAlCBub3QgZXhwcmVzc2libGUgYXMgUGFydGlhbDxFbHBoaWVNZXNzYWdlPi5cbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZU9iaiA9IHtcbiAgICAgICAgICAgICAgICBjb250ZW50OiB7ICRBUFBFTkQ6IFt0dXJuXSB9LFxuICAgICAgICAgICAgICAgIHVwZGF0ZWRfYXQ6IG5vd0lzbygpXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgdXBkYXRlZCA9IGF3YWl0IEVscGhpZU1lc3NhZ2VNb2RlbC51cGRhdGUoXG4gICAgICAgICAgICAgICAgeyBjb252ZXJzYXRpb25faWQgfSxcbiAgICAgICAgICAgICAgICB1cGRhdGVPYmogYXMgdW5rbm93biBhcyBQYXJhbWV0ZXJzPHR5cGVvZiBFbHBoaWVNZXNzYWdlTW9kZWwudXBkYXRlPlsxXSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmRpdGlvbjogbmV3IGR5bmFtb29zZS5Db25kaXRpb24oKS5hdHRyaWJ1dGUoXCJjb252ZXJzYXRpb25faWRcIikuZXhpc3RzKClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZWQgYXMgdW5rbm93biBhcyBFbHBoaWVNZXNzYWdlO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgaWYgKGlzTm90Rm91bmRFcnJvcihlcnJvcikgfHwgaXNDb25kaXRpb25hbENoZWNrRmFpbGVkKGVycm9yKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBDb252ZXJzYXRpb25Ob3RGb3VuZEVycm9yKGNvbnZlcnNhdGlvbl9pZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyB3cmFwVW5leHBlY3RlZChcImFwcGVuZFR1cm5cIiwgZXJyb3IpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZldGNoZXMgb25lIGNvbnZlcnNhdGlvbiBieSBgY29udmVyc2F0aW9uX2lkYC5cbiAgICAgKiBUaHJvd3MgYENvbnZlcnNhdGlvbk5vdEZvdW5kRXJyb3JgIHdoZW4gbWlzc2luZy5cbiAgICAgKi9cbiAgICBnZXRDb252ZXJzYXRpb24gPSBhc3luYyAoY29udmVyc2F0aW9uX2lkOiBzdHJpbmcpOiBQcm9taXNlPEVscGhpZU1lc3NhZ2U+ID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbnZlcnNhdGlvbiA9IGF3YWl0IEVscGhpZU1lc3NhZ2VNb2RlbC5nZXQoY29udmVyc2F0aW9uX2lkKTtcbiAgICAgICAgICAgIGlmICghY29udmVyc2F0aW9uKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbnZlcnNhdGlvbk5vdEZvdW5kRXJyb3IoY29udmVyc2F0aW9uX2lkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjb252ZXJzYXRpb24gYXMgRWxwaGllTWVzc2FnZTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIENvbnZlcnNhdGlvbk5vdEZvdW5kRXJyb3IpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc05vdEZvdW5kRXJyb3IoZXJyb3IpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IENvbnZlcnNhdGlvbk5vdEZvdW5kRXJyb3IoY29udmVyc2F0aW9uX2lkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IHdyYXBVbmV4cGVjdGVkKFwiZ2V0Q29udmVyc2F0aW9uXCIsIGVycm9yKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBMaXN0cyBjb252ZXJzYXRpb25zIGZvciBhIHVzZXIgdmlhIEdTSSBgdXNlcl9pZC1pbmRleGAuXG4gICAgICogTmV3ZXN0LWZpcnN0IG9yZGVyIGlzIGFwcGxpZWQgaW4gbWVtb3J5IG9uIGB1cGRhdGVkX2F0YCAobm90IGEgR1NJIHJhbmdlIGtleSkuXG4gICAgICovXG4gICAgbGlzdENvbnZlcnNhdGlvbnNGb3JVc2VyID0gYXN5bmMgKFxuICAgICAgICB1c2VyX2lkOiBzdHJpbmcsXG4gICAgICAgIHsgbGltaXQsIGxhc3RLZXkgfTogeyBsaW1pdD86IG51bWJlcjsgbGFzdEtleT86IER5bmFtb0tleSB9ID0ge31cbiAgICApOiBQcm9taXNlPExpc3RSZXN1bHQ+ID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGxldCBxdWVyeUJ1aWxkZXIgPSBFbHBoaWVNZXNzYWdlTW9kZWwucXVlcnkoXCJ1c2VyX2lkXCIpXG4gICAgICAgICAgICAgICAgLmVxKHVzZXJfaWQpXG4gICAgICAgICAgICAgICAgLnVzaW5nKFwidXNlcl9pZC1pbmRleFwiKTtcblxuICAgICAgICAgICAgaWYgKGxhc3RLZXkpIHtcbiAgICAgICAgICAgICAgICBxdWVyeUJ1aWxkZXIgPSBxdWVyeUJ1aWxkZXIuc3RhcnRBdChsYXN0S2V5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0eXBlb2YgbGltaXQgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICBxdWVyeUJ1aWxkZXIgPSBxdWVyeUJ1aWxkZXIubGltaXQobGltaXQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBxdWVyeVJlc3VsdCA9IGF3YWl0IHF1ZXJ5QnVpbGRlci5leGVjKCk7XG4gICAgICAgICAgICBjb25zdCBpdGVtcyA9IFsuLi4ocXVlcnlSZXN1bHQgYXMgdW5rbm93biBhcyBFbHBoaWVNZXNzYWdlW10pXS5zb3J0KChhLCBiKSA9PlxuICAgICAgICAgICAgICAgIChiLnVwZGF0ZWRfYXQgPz8gXCJcIikubG9jYWxlQ29tcGFyZShhLnVwZGF0ZWRfYXQgPz8gXCJcIilcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGl0ZW1zLFxuICAgICAgICAgICAgICAgIGxhc3RLZXk6IHF1ZXJ5UmVzdWx0Lmxhc3RLZXkgYXMgRHluYW1vS2V5IHwgdW5kZWZpbmVkXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgd3JhcFVuZXhwZWN0ZWQoXCJsaXN0Q29udmVyc2F0aW9uc0ZvclVzZXJcIiwgZXJyb3IpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIExpc3RzIGNvbnZlcnNhdGlvbnMgbGlua2VkIHRvIGEgc2Vzc2lvbiB2aWEgR1NJIGBlbHBoaWVTZXNzaW9uSWQtaW5kZXhgLlxuICAgICAqL1xuICAgIGxpc3RDb252ZXJzYXRpb25zRm9yU2Vzc2lvbiA9IGFzeW5jIChlbHBoaWVTZXNzaW9uSWQ6IHN0cmluZyk6IFByb21pc2U8RWxwaGllTWVzc2FnZVtdPiA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBxdWVyeVJlc3VsdCA9IGF3YWl0IEVscGhpZU1lc3NhZ2VNb2RlbC5xdWVyeShcImVscGhpZVNlc3Npb25JZFwiKVxuICAgICAgICAgICAgICAgIC5lcShlbHBoaWVTZXNzaW9uSWQpXG4gICAgICAgICAgICAgICAgLnVzaW5nKFwiZWxwaGllU2Vzc2lvbklkLWluZGV4XCIpXG4gICAgICAgICAgICAgICAgLmV4ZWMoKTtcbiAgICAgICAgICAgIHJldHVybiBxdWVyeVJlc3VsdCBhcyB1bmtub3duIGFzIEVscGhpZU1lc3NhZ2VbXTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRocm93IHdyYXBVbmV4cGVjdGVkKFwibGlzdENvbnZlcnNhdGlvbnNGb3JTZXNzaW9uXCIsIGVycm9yKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBwcml2YXRlIGFzc2VydFZhbGlkVHVybiA9ICh0dXJuOiBFbHBoaWVNZXNzYWdlVHVybik6IHZvaWQgPT4ge1xuICAgICAgICBpZiAoIXR1cm4gfHwgdHlwZW9mIHR1cm4udGV4dCAhPT0gXCJzdHJpbmdcIiB8fCB0dXJuLnRleHQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRWxwaGllVmFsaWRhdGlvbkVycm9yKFwidHVybi50ZXh0IGlzIHJlcXVpcmVkXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghaXNWYWxpZFJvbGUodHVybi5yb2xlKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVscGhpZVZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgICAgICAgICBgSW52YWxpZCB0dXJuLnJvbGUgXCIke3R1cm4ucm9sZX1cIi4gRXhwZWN0ZWQgXCJ1c2VyXCIgfCBcImVscGhpZVwiLmBcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0dXJuLnRpbWVzdGFtcCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVscGhpZVZhbGlkYXRpb25FcnJvcihcInR1cm4udGltZXN0YW1wIGlzIHJlcXVpcmVkXCIpO1xuICAgICAgICB9XG4gICAgfTtcbn1cblxuY29uc3QgaXNOb3RGb3VuZEVycm9yID0gKGVycm9yOiB1bmtub3duKTogYm9vbGVhbiA9PiB7XG4gICAgY29uc3QgbmFtZSA9IChlcnJvciBhcyB7IG5hbWU/OiBzdHJpbmcgfSB8IG51bGwpPy5uYW1lO1xuICAgIHJldHVybiBuYW1lID09PSBcIkl0ZW1Ob3RGb3VuZEV4Y2VwdGlvblwiIHx8IG5hbWUgPT09IFwiSXRlbU5vdEZvdW5kRXJyb3JcIjtcbn07XG5cbmNvbnN0IGlzQ29uZGl0aW9uYWxDaGVja0ZhaWxlZCA9IChlcnJvcjogdW5rbm93bik6IGJvb2xlYW4gPT4ge1xuICAgIGNvbnN0IG5hbWUgPSAoZXJyb3IgYXMgeyBuYW1lPzogc3RyaW5nIH0gfCBudWxsKT8ubmFtZTtcbiAgICByZXR1cm4gbmFtZSA9PT0gXCJDb25kaXRpb25hbENoZWNrRmFpbGVkRXhjZXB0aW9uXCI7XG59O1xuXG5jb25zdCB3cmFwVW5leHBlY3RlZCA9IChvcGVyYXRpb246IHN0cmluZywgZXJyb3I6IHVua25vd24pOiBFcnJvciA9PiB7XG4gICAgY29uc3QgbWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKTtcbiAgICByZXR1cm4gbmV3IEVycm9yKGBFbHBoaWVNZXNzYWdlU2VydmljZS4ke29wZXJhdGlvbn0gZmFpbGVkOiAke21lc3NhZ2V9YCk7XG59O1xuXG5leHBvcnQgY29uc3QgZWxwaGllTWVzc2FnZVNlcnZpY2UgPSBuZXcgRWxwaGllTWVzc2FnZVNlcnZpY2UoKTtcbiJdfQ==
@@ -0,0 +1,25 @@
1
+ import { Item } from "dynamoose/dist/Item";
2
+ export declare const ELPHIE_MESSAGE_ROLE: {
3
+ readonly USER: "user";
4
+ readonly ELPHIE: "elphie";
5
+ };
6
+ export type ElphieMessageRole = (typeof ELPHIE_MESSAGE_ROLE)[keyof typeof ELPHIE_MESSAGE_ROLE];
7
+ export interface ElphieMessageTurn {
8
+ role: ElphieMessageRole;
9
+ text: string;
10
+ timestamp: string;
11
+ }
12
+ export interface ElphieMessage extends Item {
13
+ conversation_id: string;
14
+ user_id: string;
15
+ elphieSessionId: string;
16
+ content: ElphieMessageTurn[];
17
+ updated_at: string;
18
+ }
19
+ export type CreateElphieConversationInput = {
20
+ conversation_id: string;
21
+ user_id: string;
22
+ elphieSessionId: string;
23
+ firstTurn: ElphieMessageTurn;
24
+ };
25
+ export declare const ElphieMessageModel: import("dynamoose/dist/General").ModelType<ElphieMessage>;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ElphieMessageModel = exports.ELPHIE_MESSAGE_ROLE = void 0;
7
+ const dynamoose_1 = __importDefault(require("dynamoose"));
8
+ const table_names_1 = require("../../config/table-names");
9
+ exports.ELPHIE_MESSAGE_ROLE = {
10
+ USER: "user",
11
+ ELPHIE: "elphie"
12
+ };
13
+ /**
14
+ * Dynamoose schema for `elphie_messages`.
15
+ *
16
+ * HASH: `conversation_id`.
17
+ * GSI `user_id-index`: HASH `user_id` only (`updated_at` is a plain attribute).
18
+ * GSI `elphieSessionId-index`: HASH `elphieSessionId` (links to `elphie_sessions`).
19
+ *
20
+ * `create: false` — tables + GSIs are provisioned via CDK, not auto-created on boot.
21
+ */
22
+ const elphieMessageSchema = new dynamoose_1.default.Schema({
23
+ conversation_id: {
24
+ type: String,
25
+ hashKey: true,
26
+ required: true
27
+ },
28
+ user_id: {
29
+ type: String,
30
+ required: true,
31
+ index: {
32
+ name: "user_id-index",
33
+ type: "global"
34
+ }
35
+ },
36
+ elphieSessionId: {
37
+ type: String,
38
+ required: true,
39
+ index: {
40
+ name: "elphieSessionId-index",
41
+ type: "global"
42
+ }
43
+ },
44
+ content: {
45
+ type: Array,
46
+ schema: [
47
+ {
48
+ type: Object,
49
+ schema: {
50
+ role: {
51
+ type: String,
52
+ required: true,
53
+ enum: [exports.ELPHIE_MESSAGE_ROLE.USER, exports.ELPHIE_MESSAGE_ROLE.ELPHIE]
54
+ },
55
+ text: {
56
+ type: String,
57
+ required: true
58
+ },
59
+ timestamp: {
60
+ type: String,
61
+ required: true
62
+ }
63
+ }
64
+ }
65
+ ],
66
+ required: true,
67
+ default: []
68
+ },
69
+ updated_at: {
70
+ type: String,
71
+ required: true
72
+ }
73
+ }, {
74
+ saveUnknown: false,
75
+ timestamps: true
76
+ });
77
+ exports.ElphieMessageModel = dynamoose_1.default.model(table_names_1.TABLE_NAMES.ELPHIE_MESSAGES, elphieMessageSchema, { create: false, waitForActive: false });
78
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxwaGllLW1lc3NhZ2UtbW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY3VzdG9tZXItdXNlci9lbHBoaWUvZWxwaGllLW1lc3NhZ2UtbW9kZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsMERBQWtDO0FBRWxDLDBEQUF1RDtBQUUxQyxRQUFBLG1CQUFtQixHQUFHO0lBQy9CLElBQUksRUFBRSxNQUFNO0lBQ1osTUFBTSxFQUFFLFFBQVE7Q0FDVixDQUFDO0FBeUJYOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLG1CQUFTLENBQUMsTUFBTSxDQUM1QztJQUNJLGVBQWUsRUFBRTtRQUNiLElBQUksRUFBRSxNQUFNO1FBQ1osT0FBTyxFQUFFLElBQUk7UUFDYixRQUFRLEVBQUUsSUFBSTtLQUNqQjtJQUNELE9BQU8sRUFBRTtRQUNMLElBQUksRUFBRSxNQUFNO1FBQ1osUUFBUSxFQUFFLElBQUk7UUFDZCxLQUFLLEVBQUU7WUFDSCxJQUFJLEVBQUUsZUFBZTtZQUNyQixJQUFJLEVBQUUsUUFBUTtTQUNqQjtLQUNKO0lBQ0QsZUFBZSxFQUFFO1FBQ2IsSUFBSSxFQUFFLE1BQU07UUFDWixRQUFRLEVBQUUsSUFBSTtRQUNkLEtBQUssRUFBRTtZQUNILElBQUksRUFBRSx1QkFBdUI7WUFDN0IsSUFBSSxFQUFFLFFBQVE7U0FDakI7S0FDSjtJQUNELE9BQU8sRUFBRTtRQUNMLElBQUksRUFBRSxLQUFLO1FBQ1gsTUFBTSxFQUFFO1lBQ0o7Z0JBQ0ksSUFBSSxFQUFFLE1BQU07Z0JBQ1osTUFBTSxFQUFFO29CQUNKLElBQUksRUFBRTt3QkFDRixJQUFJLEVBQUUsTUFBTTt3QkFDWixRQUFRLEVBQUUsSUFBSTt3QkFDZCxJQUFJLEVBQUUsQ0FBQywyQkFBbUIsQ0FBQyxJQUFJLEVBQUUsMkJBQW1CLENBQUMsTUFBTSxDQUFDO3FCQUMvRDtvQkFDRCxJQUFJLEVBQUU7d0JBQ0YsSUFBSSxFQUFFLE1BQU07d0JBQ1osUUFBUSxFQUFFLElBQUk7cUJBQ2pCO29CQUNELFNBQVMsRUFBRTt3QkFDUCxJQUFJLEVBQUUsTUFBTTt3QkFDWixRQUFRLEVBQUUsSUFBSTtxQkFDakI7aUJBQ0o7YUFDSjtTQUNKO1FBQ0QsUUFBUSxFQUFFLElBQUk7UUFDZCxPQUFPLEVBQUUsRUFBRTtLQUNkO0lBQ0QsVUFBVSxFQUFFO1FBQ1IsSUFBSSxFQUFFLE1BQU07UUFDWixRQUFRLEVBQUUsSUFBSTtLQUNqQjtDQUNKLEVBQ0Q7SUFDSSxXQUFXLEVBQUUsS0FBSztJQUNsQixVQUFVLEVBQUUsSUFBSTtDQUNuQixDQUNKLENBQUM7QUFFVyxRQUFBLGtCQUFrQixHQUFHLG1CQUFTLENBQUMsS0FBSyxDQUM3Qyx5QkFBVyxDQUFDLGVBQWUsRUFDM0IsbUJBQW1CLEVBQ25CLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLENBQzFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZHluYW1vb3NlIGZyb20gXCJkeW5hbW9vc2VcIjtcbmltcG9ydCB7IEl0ZW0gfSBmcm9tIFwiZHluYW1vb3NlL2Rpc3QvSXRlbVwiO1xuaW1wb3J0IHsgVEFCTEVfTkFNRVMgfSBmcm9tIFwiLi4vLi4vY29uZmlnL3RhYmxlLW5hbWVzXCI7XG5cbmV4cG9ydCBjb25zdCBFTFBISUVfTUVTU0FHRV9ST0xFID0ge1xuICAgIFVTRVI6IFwidXNlclwiLFxuICAgIEVMUEhJRTogXCJlbHBoaWVcIlxufSBhcyBjb25zdDtcblxuZXhwb3J0IHR5cGUgRWxwaGllTWVzc2FnZVJvbGUgPSAodHlwZW9mIEVMUEhJRV9NRVNTQUdFX1JPTEUpW2tleW9mIHR5cGVvZiBFTFBISUVfTUVTU0FHRV9ST0xFXTtcblxuZXhwb3J0IGludGVyZmFjZSBFbHBoaWVNZXNzYWdlVHVybiB7XG4gICAgcm9sZTogRWxwaGllTWVzc2FnZVJvbGU7XG4gICAgdGV4dDogc3RyaW5nO1xuICAgIHRpbWVzdGFtcDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEVscGhpZU1lc3NhZ2UgZXh0ZW5kcyBJdGVtIHtcbiAgICBjb252ZXJzYXRpb25faWQ6IHN0cmluZztcbiAgICB1c2VyX2lkOiBzdHJpbmc7XG4gICAgZWxwaGllU2Vzc2lvbklkOiBzdHJpbmc7XG4gICAgY29udGVudDogRWxwaGllTWVzc2FnZVR1cm5bXTtcbiAgICB1cGRhdGVkX2F0OiBzdHJpbmc7XG59XG5cbmV4cG9ydCB0eXBlIENyZWF0ZUVscGhpZUNvbnZlcnNhdGlvbklucHV0ID0ge1xuICAgIGNvbnZlcnNhdGlvbl9pZDogc3RyaW5nO1xuICAgIHVzZXJfaWQ6IHN0cmluZztcbiAgICBlbHBoaWVTZXNzaW9uSWQ6IHN0cmluZztcbiAgICBmaXJzdFR1cm46IEVscGhpZU1lc3NhZ2VUdXJuO1xufTtcblxuLyoqXG4gKiBEeW5hbW9vc2Ugc2NoZW1hIGZvciBgZWxwaGllX21lc3NhZ2VzYC5cbiAqXG4gKiBIQVNIOiBgY29udmVyc2F0aW9uX2lkYC5cbiAqIEdTSSBgdXNlcl9pZC1pbmRleGA6IEhBU0ggYHVzZXJfaWRgIG9ubHkgKGB1cGRhdGVkX2F0YCBpcyBhIHBsYWluIGF0dHJpYnV0ZSkuXG4gKiBHU0kgYGVscGhpZVNlc3Npb25JZC1pbmRleGA6IEhBU0ggYGVscGhpZVNlc3Npb25JZGAgKGxpbmtzIHRvIGBlbHBoaWVfc2Vzc2lvbnNgKS5cbiAqXG4gKiBgY3JlYXRlOiBmYWxzZWAg4oCUIHRhYmxlcyArIEdTSXMgYXJlIHByb3Zpc2lvbmVkIHZpYSBDREssIG5vdCBhdXRvLWNyZWF0ZWQgb24gYm9vdC5cbiAqL1xuY29uc3QgZWxwaGllTWVzc2FnZVNjaGVtYSA9IG5ldyBkeW5hbW9vc2UuU2NoZW1hKFxuICAgIHtcbiAgICAgICAgY29udmVyc2F0aW9uX2lkOiB7XG4gICAgICAgICAgICB0eXBlOiBTdHJpbmcsXG4gICAgICAgICAgICBoYXNoS2V5OiB0cnVlLFxuICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAgdXNlcl9pZDoge1xuICAgICAgICAgICAgdHlwZTogU3RyaW5nLFxuICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBpbmRleDoge1xuICAgICAgICAgICAgICAgIG5hbWU6IFwidXNlcl9pZC1pbmRleFwiLFxuICAgICAgICAgICAgICAgIHR5cGU6IFwiZ2xvYmFsXCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZWxwaGllU2Vzc2lvbklkOiB7XG4gICAgICAgICAgICB0eXBlOiBTdHJpbmcsXG4gICAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgIGluZGV4OiB7XG4gICAgICAgICAgICAgICAgbmFtZTogXCJlbHBoaWVTZXNzaW9uSWQtaW5kZXhcIixcbiAgICAgICAgICAgICAgICB0eXBlOiBcImdsb2JhbFwiXG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGNvbnRlbnQ6IHtcbiAgICAgICAgICAgIHR5cGU6IEFycmF5LFxuICAgICAgICAgICAgc2NoZW1hOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiBPYmplY3QsXG4gICAgICAgICAgICAgICAgICAgIHNjaGVtYToge1xuICAgICAgICAgICAgICAgICAgICAgICAgcm9sZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFN0cmluZyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnVtOiBbRUxQSElFX01FU1NBR0VfUk9MRS5VU0VSLCBFTFBISUVfTUVTU0FHRV9ST0xFLkVMUEhJRV1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB0ZXh0OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogU3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGltZXN0YW1wOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogU3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVpcmVkOiB0cnVlXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgICAgICBkZWZhdWx0OiBbXVxuICAgICAgICB9LFxuICAgICAgICB1cGRhdGVkX2F0OiB7XG4gICAgICAgICAgICB0eXBlOiBTdHJpbmcsXG4gICAgICAgICAgICByZXF1aXJlZDogdHJ1ZVxuICAgICAgICB9XG4gICAgfSxcbiAgICB7XG4gICAgICAgIHNhdmVVbmtub3duOiBmYWxzZSxcbiAgICAgICAgdGltZXN0YW1wczogdHJ1ZVxuICAgIH1cbik7XG5cbmV4cG9ydCBjb25zdCBFbHBoaWVNZXNzYWdlTW9kZWwgPSBkeW5hbW9vc2UubW9kZWw8RWxwaGllTWVzc2FnZT4oXG4gICAgVEFCTEVfTkFNRVMuRUxQSElFX01FU1NBR0VTLFxuICAgIGVscGhpZU1lc3NhZ2VTY2hlbWEsXG4gICAgeyBjcmVhdGU6IGZhbHNlLCB3YWl0Rm9yQWN0aXZlOiBmYWxzZSB9XG4pO1xuIl19
@@ -0,0 +1,46 @@
1
+ import { DynamoKey } from "../../base-dynamoose-dao";
2
+ import { CreateElphieSessionInput, ElphieSession } from "./elphie-session-model";
3
+ type ListResult = {
4
+ items: ElphieSession[];
5
+ lastKey?: DynamoKey;
6
+ };
7
+ /**
8
+ * Service/DAO for `elphie_sessions`.
9
+ *
10
+ * HASH: `elphieSessionId` (UUID set here — never schema-defaulted).
11
+ * List-by-user: GSI `user_id-index`.
12
+ */
13
+ declare class ElphieSessionService {
14
+ /**
15
+ * Creates a session. Generates `elphieSessionId` via `randomUUID()` and stamps ISO UTC times.
16
+ *
17
+ * @example
18
+ * const session = await elphieSessionService.createSession({
19
+ * user_id: "user-1",
20
+ * conversation_id: "conv-1",
21
+ * title: "Birthday planning",
22
+ * fmp_context: { occasion: "birthday" }
23
+ * });
24
+ */
25
+ createSession: (input: CreateElphieSessionInput) => Promise<ElphieSession>;
26
+ /**
27
+ * Fetches one session by `elphieSessionId`.
28
+ * Throws `SessionNotFoundError` when missing.
29
+ */
30
+ getSessionById: (elphieSessionId: string) => Promise<ElphieSession>;
31
+ /**
32
+ * Lists sessions for a user via GSI `user_id-index`.
33
+ * Newest-first order is applied in memory on `created_at` (not a GSI range key).
34
+ * Pass `lastKey` from the previous response for pagination.
35
+ */
36
+ listSessionsForUser: (user_id: string, { limit, lastKey }?: {
37
+ limit?: number;
38
+ lastKey?: DynamoKey;
39
+ }) => Promise<ListResult>;
40
+ /**
41
+ * Atomically updates session `title` + `updated_at`.
42
+ */
43
+ updateSessionTitle: (elphieSessionId: string, title: string) => Promise<ElphieSession>;
44
+ }
45
+ export declare const elphieSessionService: ElphieSessionService;
46
+ export {};
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.elphieSessionService = void 0;
7
+ const crypto_1 = require("crypto");
8
+ const dynamoose_1 = __importDefault(require("dynamoose"));
9
+ const elphie_errors_1 = require("./elphie-errors");
10
+ const elphie_session_model_1 = require("./elphie-session-model");
11
+ const nowIso = () => new Date().toISOString();
12
+ /**
13
+ * Service/DAO for `elphie_sessions`.
14
+ *
15
+ * HASH: `elphieSessionId` (UUID set here — never schema-defaulted).
16
+ * List-by-user: GSI `user_id-index`.
17
+ */
18
+ class ElphieSessionService {
19
+ constructor() {
20
+ /**
21
+ * Creates a session. Generates `elphieSessionId` via `randomUUID()` and stamps ISO UTC times.
22
+ *
23
+ * @example
24
+ * const session = await elphieSessionService.createSession({
25
+ * user_id: "user-1",
26
+ * conversation_id: "conv-1",
27
+ * title: "Birthday planning",
28
+ * fmp_context: { occasion: "birthday" }
29
+ * });
30
+ */
31
+ this.createSession = async (input) => {
32
+ try {
33
+ const now = nowIso();
34
+ const created = await elphie_session_model_1.ElphieSessionModel.create({
35
+ elphieSessionId: (0, crypto_1.randomUUID)(),
36
+ user_id: input.user_id,
37
+ conversation_id: input.conversation_id,
38
+ title: input.title,
39
+ fmp_context: input.fmp_context,
40
+ created_at: now,
41
+ updated_at: now
42
+ });
43
+ return created;
44
+ }
45
+ catch (error) {
46
+ throw wrapUnexpected("createSession", error);
47
+ }
48
+ };
49
+ /**
50
+ * Fetches one session by `elphieSessionId`.
51
+ * Throws `SessionNotFoundError` when missing.
52
+ */
53
+ this.getSessionById = async (elphieSessionId) => {
54
+ try {
55
+ const session = await elphie_session_model_1.ElphieSessionModel.get(elphieSessionId);
56
+ if (!session) {
57
+ throw new elphie_errors_1.SessionNotFoundError(elphieSessionId);
58
+ }
59
+ return session;
60
+ }
61
+ catch (error) {
62
+ if (error instanceof elphie_errors_1.SessionNotFoundError) {
63
+ throw error;
64
+ }
65
+ // Dynamoose may throw ItemNotFoundError depending on settings
66
+ if (isNotFoundError(error)) {
67
+ throw new elphie_errors_1.SessionNotFoundError(elphieSessionId);
68
+ }
69
+ throw wrapUnexpected("getSessionById", error);
70
+ }
71
+ };
72
+ /**
73
+ * Lists sessions for a user via GSI `user_id-index`.
74
+ * Newest-first order is applied in memory on `created_at` (not a GSI range key).
75
+ * Pass `lastKey` from the previous response for pagination.
76
+ */
77
+ this.listSessionsForUser = async (user_id, { limit, lastKey } = {}) => {
78
+ try {
79
+ let queryBuilder = elphie_session_model_1.ElphieSessionModel.query("user_id")
80
+ .eq(user_id)
81
+ .using("user_id-index");
82
+ if (lastKey) {
83
+ queryBuilder = queryBuilder.startAt(lastKey);
84
+ }
85
+ if (typeof limit === "number") {
86
+ queryBuilder = queryBuilder.limit(limit);
87
+ }
88
+ const queryResult = await queryBuilder.exec();
89
+ const items = [...queryResult].sort((a, b) => (b.created_at ?? "").localeCompare(a.created_at ?? ""));
90
+ return {
91
+ items,
92
+ lastKey: queryResult.lastKey
93
+ };
94
+ }
95
+ catch (error) {
96
+ throw wrapUnexpected("listSessionsForUser", error);
97
+ }
98
+ };
99
+ /**
100
+ * Atomically updates session `title` + `updated_at`.
101
+ */
102
+ this.updateSessionTitle = async (elphieSessionId, title) => {
103
+ try {
104
+ const updated = await elphie_session_model_1.ElphieSessionModel.update({ elphieSessionId }, {
105
+ title,
106
+ updated_at: nowIso()
107
+ }, {
108
+ condition: new dynamoose_1.default.Condition().attribute("elphieSessionId").exists()
109
+ });
110
+ return updated;
111
+ }
112
+ catch (error) {
113
+ if (isNotFoundError(error) || isConditionalCheckFailed(error)) {
114
+ throw new elphie_errors_1.SessionNotFoundError(elphieSessionId);
115
+ }
116
+ throw wrapUnexpected("updateSessionTitle", error);
117
+ }
118
+ };
119
+ }
120
+ }
121
+ const isNotFoundError = (error) => {
122
+ const name = error?.name;
123
+ return name === "ItemNotFoundException" || name === "ItemNotFoundError";
124
+ };
125
+ const isConditionalCheckFailed = (error) => {
126
+ const name = error?.name;
127
+ return name === "ConditionalCheckFailedException";
128
+ };
129
+ const wrapUnexpected = (operation, error) => {
130
+ const message = error instanceof Error ? error.message : String(error);
131
+ return new Error(`ElphieSessionService.${operation} failed: ${message}`);
132
+ };
133
+ exports.elphieSessionService = new ElphieSessionService();
134
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxwaGllLXNlc3Npb24tZGFvLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2N1c3RvbWVyLXVzZXIvZWxwaGllL2VscGhpZS1zZXNzaW9uLWRhby50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxtQ0FBb0M7QUFDcEMsMERBQWtDO0FBRWxDLG1EQUF1RDtBQUN2RCxpRUFJZ0M7QUFPaEMsTUFBTSxNQUFNLEdBQUcsR0FBVyxFQUFFLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQztBQUV0RDs7Ozs7R0FLRztBQUNILE1BQU0sb0JBQW9CO0lBQTFCO1FBQ0k7Ozs7Ozs7Ozs7V0FVRztRQUNILGtCQUFhLEdBQUcsS0FBSyxFQUFFLEtBQStCLEVBQTBCLEVBQUU7WUFDOUUsSUFBSSxDQUFDO2dCQUNELE1BQU0sR0FBRyxHQUFHLE1BQU0sRUFBRSxDQUFDO2dCQUNyQixNQUFNLE9BQU8sR0FBRyxNQUFNLHlDQUFrQixDQUFDLE1BQU0sQ0FBQztvQkFDNUMsZUFBZSxFQUFFLElBQUEsbUJBQVUsR0FBRTtvQkFDN0IsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO29CQUN0QixlQUFlLEVBQUUsS0FBSyxDQUFDLGVBQWU7b0JBQ3RDLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSztvQkFDbEIsV0FBVyxFQUFFLEtBQUssQ0FBQyxXQUFXO29CQUM5QixVQUFVLEVBQUUsR0FBRztvQkFDZixVQUFVLEVBQUUsR0FBRztpQkFDbEIsQ0FBQyxDQUFDO2dCQUNILE9BQU8sT0FBd0IsQ0FBQztZQUNwQyxDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDYixNQUFNLGNBQWMsQ0FBQyxlQUFlLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDakQsQ0FBQztRQUNMLENBQUMsQ0FBQztRQUVGOzs7V0FHRztRQUNILG1CQUFjLEdBQUcsS0FBSyxFQUFFLGVBQXVCLEVBQTBCLEVBQUU7WUFDdkUsSUFBSSxD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QkFBb0IsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN0RCxDQUFDO1FBQ0wsQ0FBQyxDQUFDO0lBQ04sQ0FBQztDQUFBO0FBRUQsTUFBTSxlQUFlLEdBQUcsQ0FBQyxLQUFjLEVBQVcsRUFBRTtJQUNoRCxNQUFNLElBQUksR0FBSSxLQUFrQyxFQUFFLElBQUksQ0FBQztJQUN2RCxPQUFPLElBQUksS0FBSyx1QkFBdUIsSUFBSSxJQUFJLEtBQUssbUJBQW1CLENBQUM7QUFDNUUsQ0FBQyxDQUFDO0FBRUYsTUFBTSx3QkFBd0IsR0FBRyxDQUFDLEtBQWMsRUFBVyxFQUFFO0lBQ3pELE1BQU0sSUFBSSxHQUFJLEtBQWtDLEVBQUUsSUFBSSxDQUFDO0lBQ3ZELE9BQU8sSUFBSSxLQUFLLGlDQUFpQyxDQUFDO0FBQ3RELENBQUMsQ0FBQztBQUVGLE1BQU0sY0FBYyxHQUFHLENBQUMsU0FBaUIsRUFBRSxLQUFjLEVBQVMsRUFBRTtJQUNoRSxNQUFNLE9BQU8sR0FBRyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdkUsT0FBTyxJQUFJLEtBQUssQ0FBQyx3QkFBd0IsU0FBUyxZQUFZLE9BQU8sRUFBRSxDQUFDLENBQUM7QUFDN0UsQ0FBQyxDQUFDO0FBRVcsUUFBQSxvQkFBb0IsR0FBRyxJQUFJLG9CQUFvQixFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyByYW5kb21VVUlEIH0gZnJvbSBcImNyeXB0b1wiO1xuaW1wb3J0IGR5bmFtb29zZSBmcm9tIFwiZHluYW1vb3NlXCI7XG5pbXBvcnQgeyBEeW5hbW9LZXkgfSBmcm9tIFwiLi4vLi4vYmFzZS1keW5hbW9vc2UtZGFvXCI7XG5pbXBvcnQgeyBTZXNzaW9uTm90Rm91bmRFcnJvciB9IGZyb20gXCIuL2VscGhpZS1lcnJvcnNcIjtcbmltcG9ydCB7XG4gICAgQ3JlYXRlRWxwaGllU2Vzc2lvbklucHV0LFxuICAgIEVscGhpZVNlc3Npb24sXG4gICAgRWxwaGllU2Vzc2lvbk1vZGVsXG59IGZyb20gXCIuL2VscGhpZS1zZXNzaW9uLW1vZGVsXCI7XG5cbnR5cGUgTGlzdFJlc3VsdCA9IHtcbiAgICBpdGVtczogRWxwaGllU2Vzc2lvbltdO1xuICAgIGxhc3RLZXk/OiBEeW5hbW9LZXk7XG59O1xuXG5jb25zdCBub3dJc28gPSAoKTogc3RyaW5nID0+IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcblxuLyoqXG4gKiBTZXJ2aWNlL0RBTyBmb3IgYGVscGhpZV9zZXNzaW9uc2AuXG4gKlxuICogSEFTSDogYGVscGhpZVNlc3Npb25JZGAgKFVVSUQgc2V0IGhlcmUg4oCUIG5ldmVyIHNjaGVtYS1kZWZhdWx0ZWQpLlxuICogTGlzdC1ieS11c2VyOiBHU0kgYHVzZXJfaWQtaW5kZXhgLlxuICovXG5jbGFzcyBFbHBoaWVTZXNzaW9uU2VydmljZSB7XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHNlc3Npb24uIEdlbmVyYXRlcyBgZWxwaGllU2Vzc2lvbklkYCB2aWEgYHJhbmRvbVVVSUQoKWAgYW5kIHN0YW1wcyBJU08gVVRDIHRpbWVzLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzZXNzaW9uID0gYXdhaXQgZWxwaGllU2Vzc2lvblNlcnZpY2UuY3JlYXRlU2Vzc2lvbih7XG4gICAgICogICAgIHVzZXJfaWQ6IFwidXNlci0xXCIsXG4gICAgICogICAgIGNvbnZlcnNhdGlvbl9pZDogXCJjb252LTFcIixcbiAgICAgKiAgICAgdGl0bGU6IFwiQmlydGhkYXkgcGxhbm5pbmdcIixcbiAgICAgKiAgICAgZm1wX2NvbnRleHQ6IHsgb2NjYXNpb246IFwiYmlydGhkYXlcIiB9XG4gICAgICogfSk7XG4gICAgICovXG4gICAgY3JlYXRlU2Vzc2lvbiA9IGFzeW5jIChpbnB1dDogQ3JlYXRlRWxwaGllU2Vzc2lvbklucHV0KTogUHJvbWlzZTxFbHBoaWVTZXNzaW9uPiA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBub3cgPSBub3dJc28oKTtcbiAgICAgICAgICAgIGNvbnN0IGNyZWF0ZWQgPSBhd2FpdCBFbHBoaWVTZXNzaW9uTW9kZWwuY3JlYXRlKHtcbiAgICAgICAgICAgICAgICBlbHBoaWVTZXNzaW9uSWQ6IHJhbmRvbVVVSUQoKSxcbiAgICAgICAgICAgICAgICB1c2VyX2lkOiBpbnB1dC51c2VyX2lkLFxuICAgICAgICAgICAgICAgIGNvbnZlcnNhdGlvbl9pZDogaW5wdXQuY29udmVyc2F0aW9uX2lkLFxuICAgICAgICAgICAgICAgIHRpdGxlOiBpbnB1dC50aXRsZSxcbiAgICAgICAgICAgICAgICBmbXBfY29udGV4dDogaW5wdXQuZm1wX2NvbnRleHQsXG4gICAgICAgICAgICAgICAgY3JlYXRlZF9hdDogbm93LFxuICAgICAgICAgICAgICAgIHVwZGF0ZWRfYXQ6IG5vd1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlZCBhcyBFbHBoaWVTZXNzaW9uO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgd3JhcFVuZXhwZWN0ZWQoXCJjcmVhdGVTZXNzaW9uXCIsIGVycm9yKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIG9uZSBzZXNzaW9uIGJ5IGBlbHBoaWVTZXNzaW9uSWRgLlxuICAgICAqIFRocm93cyBgU2Vzc2lvbk5vdEZvdW5kRXJyb3JgIHdoZW4gbWlzc2luZy5cbiAgICAgKi9cbiAgICBnZXRTZXNzaW9uQnlJZCA9IGFzeW5jIChlbHBoaWVTZXNzaW9uSWQ6IHN0cmluZyk6IFByb21pc2U8RWxwaGllU2Vzc2lvbj4gPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IGF3YWl0IEVscGhpZVNlc3Npb25Nb2RlbC5nZXQoZWxwaGllU2Vzc2lvbklkKTtcbiAgICAgICAgICAgIGlmICghc2Vzc2lvbikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBTZXNzaW9uTm90Rm91bmRFcnJvcihlbHBoaWVTZXNzaW9uSWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHNlc3Npb24gYXMgRWxwaGllU2Vzc2lvbjtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFNlc3Npb25Ob3RGb3VuZEVycm9yKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBEeW5hbW9vc2UgbWF5IHRocm93IEl0ZW1Ob3RGb3VuZEVycm9yIGRlcGVuZGluZyBvbiBzZXR0aW5nc1xuICAgICAgICAgICAgaWYgKGlzTm90Rm91bmRFcnJvcihlcnJvcikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU2Vzc2lvbk5vdEZvdW5kRXJyb3IoZWxwaGllU2Vzc2lvbklkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IHdyYXBVbmV4cGVjdGVkKFwiZ2V0U2Vzc2lvbkJ5SWRcIiwgZXJyb3IpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIExpc3RzIHNlc3Npb25zIGZvciBhIHVzZXIgdmlhIEdTSSBgdXNlcl9pZC1pbmRleGAuXG4gICAgICogTmV3ZXN0LWZpcnN0IG9yZGVyIGlzIGFwcGxpZWQgaW4gbWVtb3J5IG9uIGBjcmVhdGVkX2F0YCAobm90IGEgR1NJIHJhbmdlIGtleSkuXG4gICAgICogUGFzcyBgbGFzdEtleWAgZnJvbSB0aGUgcHJldmlvdXMgcmVzcG9uc2UgZm9yIHBhZ2luYXRpb24uXG4gICAgICovXG4gICAgbGlzdFNlc3Npb25zRm9yVXNlciA9IGFzeW5jIChcbiAgICAgICAgdXNlcl9pZDogc3RyaW5nLFxuICAgICAgICB7IGxpbWl0LCBsYXN0S2V5IH06IHsgbGltaXQ/OiBudW1iZXI7IGxhc3RLZXk/OiBEeW5hbW9LZXkgfSA9IHt9XG4gICAgKTogUHJvbWlzZTxMaXN0UmVzdWx0PiA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgcXVlcnlCdWlsZGVyID0gRWxwaGllU2Vzc2lvbk1vZGVsLnF1ZXJ5KFwidXNlcl9pZFwiKVxuICAgICAgICAgICAgICAgIC5lcSh1c2VyX2lkKVxuICAgICAgICAgICAgICAgIC51c2luZyhcInVzZXJfaWQtaW5kZXhcIik7XG5cbiAgICAgICAgICAgIGlmIChsYXN0S2V5KSB7XG4gICAgICAgICAgICAgICAgcXVlcnlCdWlsZGVyID0gcXVlcnlCdWlsZGVyLnN0YXJ0QXQobGFzdEtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZW9mIGxpbWl0ID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgcXVlcnlCdWlsZGVyID0gcXVlcnlCdWlsZGVyLmxpbWl0KGxpbWl0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgcXVlcnlSZXN1bHQgPSBhd2FpdCBxdWVyeUJ1aWxkZXIuZXhlYygpO1xuICAgICAgICAgICAgY29uc3QgaXRlbXMgPSBbLi4uKHF1ZXJ5UmVzdWx0IGFzIHVua25vd24gYXMgRWxwaGllU2Vzc2lvbltdKV0uc29ydCgoYSwgYikgPT5cbiAgICAgICAgICAgICAgICAoYi5jcmVhdGVkX2F0ID8/IFwiXCIpLmxvY2FsZUNvbXBhcmUoYS5jcmVhdGVkX2F0ID8/IFwiXCIpXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBpdGVtcyxcbiAgICAgICAgICAgICAgICBsYXN0S2V5OiBxdWVyeVJlc3VsdC5sYXN0S2V5IGFzIER5bmFtb0tleSB8IHVuZGVmaW5lZFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRocm93IHdyYXBVbmV4cGVjdGVkKFwibGlzdFNlc3Npb25zRm9yVXNlclwiLCBlcnJvcik7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQXRvbWljYWxseSB1cGRhdGVzIHNlc3Npb24gYHRpdGxlYCArIGB1cGRhdGVkX2F0YC5cbiAgICAgKi9cbiAgICB1cGRhdGVTZXNzaW9uVGl0bGUgPSBhc3luYyAoZWxwaGllU2Vzc2lvbklkOiBzdHJpbmcsIHRpdGxlOiBzdHJpbmcpOiBQcm9taXNlPEVscGhpZVNlc3Npb24+ID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZWQgPSBhd2FpdCBFbHBoaWVTZXNzaW9uTW9kZWwudXBkYXRlKFxuICAgICAgICAgICAgICAgIHsgZWxwaGllU2Vzc2lvbklkIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICB0aXRsZSxcbiAgICAgICAgICAgICAgICAgICAgdXBkYXRlZF9hdDogbm93SXNvKClcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29uZGl0aW9uOiBuZXcgZHluYW1vb3NlLkNvbmRpdGlvbigpLmF0dHJpYnV0ZShcImVscGhpZVNlc3Npb25JZFwiKS5leGlzdHMoKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm4gdXBkYXRlZCBhcyB1bmtub3duIGFzIEVscGhpZVNlc3Npb247XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBpZiAoaXNOb3RGb3VuZEVycm9yKGVycm9yKSB8fCBpc0NvbmRpdGlvbmFsQ2hlY2tGYWlsZWQoZXJyb3IpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNlc3Npb25Ob3RGb3VuZEVycm9yKGVscGhpZVNlc3Npb25JZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyB3cmFwVW5leHBlY3RlZChcInVwZGF0ZVNlc3Npb25UaXRsZVwiLCBlcnJvcik7XG4gICAgICAgIH1cbiAgICB9O1xufVxuXG5jb25zdCBpc05vdEZvdW5kRXJyb3IgPSAoZXJyb3I6IHVua25vd24pOiBib29sZWFuID0+IHtcbiAgICBjb25zdCBuYW1lID0gKGVycm9yIGFzIHsgbmFtZT86IHN0cmluZyB9IHwgbnVsbCk/Lm5hbWU7XG4gICAgcmV0dXJuIG5hbWUgPT09IFwiSXRlbU5vdEZvdW5kRXhjZXB0aW9uXCIgfHwgbmFtZSA9PT0gXCJJdGVtTm90Rm91bmRFcnJvclwiO1xufTtcblxuY29uc3QgaXNDb25kaXRpb25hbENoZWNrRmFpbGVkID0gKGVycm9yOiB1bmtub3duKTogYm9vbGVhbiA9PiB7XG4gICAgY29uc3QgbmFtZSA9IChlcnJvciBhcyB7IG5hbWU/OiBzdHJpbmcgfSB8IG51bGwpPy5uYW1lO1xuICAgIHJldHVybiBuYW1lID09PSBcIkNvbmRpdGlvbmFsQ2hlY2tGYWlsZWRFeGNlcHRpb25cIjtcbn07XG5cbmNvbnN0IHdyYXBVbmV4cGVjdGVkID0gKG9wZXJhdGlvbjogc3RyaW5nLCBlcnJvcjogdW5rbm93bik6IEVycm9yID0+IHtcbiAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpO1xuICAgIHJldHVybiBuZXcgRXJyb3IoYEVscGhpZVNlc3Npb25TZXJ2aWNlLiR7b3BlcmF0aW9ufSBmYWlsZWQ6ICR7bWVzc2FnZX1gKTtcbn07XG5cbmV4cG9ydCBjb25zdCBlbHBoaWVTZXNzaW9uU2VydmljZSA9IG5ldyBFbHBoaWVTZXNzaW9uU2VydmljZSgpO1xuIl19