@livepreso/api 6.53.1 → 6.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/.rush/temp/chunked-rush-logs/api.build.chunks.jsonl +2 -2
  2. package/.rush/temp/operation/build/all.log +2 -2
  3. package/.rush/temp/operation/build/error.log +1 -1
  4. package/.rush/temp/operation/build/log-chunks.jsonl +2 -2
  5. package/.rush/temp/operation/build/state.json +1 -1
  6. package/.rush/temp/shrinkwrap-deps.json +65 -15
  7. package/CHANGELOG.json +46 -0
  8. package/CHANGELOG.md +27 -1
  9. package/cjs/api.js +1 -1
  10. package/cjs/api.js.map +1 -1
  11. package/cjs/collections/auto-adjuncts.js +0 -22
  12. package/cjs/collections/auto-adjuncts.js.map +1 -1
  13. package/cjs/collections/cms-vals.js +25 -0
  14. package/cjs/collections/cms-vals.js.map +1 -1
  15. package/cjs/collections/cms-vals.spec.js +73 -0
  16. package/cjs/collections/cms-vals.spec.js.map +1 -0
  17. package/cjs/collections/deck-version-screenshots.js +0 -23
  18. package/cjs/collections/deck-version-screenshots.js.map +1 -1
  19. package/cjs/collections/scenarios.js +20 -0
  20. package/cjs/collections/scenarios.js.map +1 -0
  21. package/cjs/collections.js +11 -22
  22. package/cjs/collections.js.map +1 -1
  23. package/cjs/fixtures.js +18 -1
  24. package/cjs/fixtures.js.map +1 -1
  25. package/cjs/middlewares/base.js +1 -2
  26. package/cjs/middlewares/base.js.map +1 -1
  27. package/cjs/models/appointment.js +29 -8
  28. package/cjs/models/appointment.js.map +1 -1
  29. package/cjs/models/auto-adjunct.js +3 -2
  30. package/cjs/models/auto-adjunct.js.map +1 -1
  31. package/cjs/models/base.js +3 -1
  32. package/cjs/models/base.js.map +1 -1
  33. package/cjs/models/cms-val.js +3 -3
  34. package/cjs/models/cms-val.js.map +1 -1
  35. package/cjs/models/customer.js +2 -1
  36. package/cjs/models/customer.js.map +1 -1
  37. package/cjs/models/deck-layout.js +52 -0
  38. package/cjs/models/deck-layout.js.map +1 -0
  39. package/cjs/models/deck-version-screenshot.js +2 -2
  40. package/cjs/models/deck-version-screenshot.js.map +1 -1
  41. package/cjs/models/deck-version.js +43 -20
  42. package/cjs/models/deck-version.js.map +1 -1
  43. package/cjs/models/image.js +0 -2
  44. package/cjs/models/image.js.map +1 -1
  45. package/cjs/models/pack-diff.js +18 -9
  46. package/cjs/models/pack-diff.js.map +1 -1
  47. package/cjs/models/preset.js +8 -6
  48. package/cjs/models/preset.js.map +1 -1
  49. package/cjs/models/scenario.js +41 -0
  50. package/cjs/models/scenario.js.map +1 -0
  51. package/cjs/models/user.js +8 -3
  52. package/cjs/models/user.js.map +1 -1
  53. package/cjs/models.js +22 -0
  54. package/cjs/models.js.map +1 -1
  55. package/cjs/presentation/appointment-presentation.js +5 -3
  56. package/cjs/presentation/appointment-presentation.js.map +1 -1
  57. package/cjs/presentation/base-presentation-model.js +26 -23
  58. package/cjs/presentation/base-presentation-model.js.map +1 -1
  59. package/cjs/presentation/base-presentation-model.spec.js +21 -21
  60. package/cjs/presentation/base-presentation-model.spec.js.map +1 -1
  61. package/cjs/presentation/presentation-deck.js +6 -0
  62. package/cjs/presentation/presentation-deck.js.map +1 -1
  63. package/cjs/presentation/presentation-section.js +28 -3
  64. package/cjs/presentation/presentation-section.js.map +1 -1
  65. package/cjs/presentation/presentation-section.spec.js +16 -3
  66. package/cjs/presentation/presentation-section.spec.js.map +1 -1
  67. package/cjs/presentation/presentation-slide.js +25 -1
  68. package/cjs/presentation/presentation-slide.js.map +1 -1
  69. package/cjs/presentation/presentation-slide.spec.js +8 -1
  70. package/cjs/presentation/presentation-slide.spec.js.map +1 -1
  71. package/cjs/sync.js +17 -9
  72. package/cjs/sync.js.map +1 -1
  73. package/cjs/utils.js +12 -3
  74. package/cjs/utils.js.map +1 -1
  75. package/cjs/utils.spec.js +22 -0
  76. package/cjs/utils.spec.js.map +1 -1
  77. package/package.json +1 -1
  78. package/rush-logs/api.build.error.log +1 -1
  79. package/rush-logs/api.build.log +2 -2
  80. package/src/api.js +1 -1
  81. package/src/collections/auto-adjuncts.js +0 -22
  82. package/src/collections/cms-vals.js +28 -0
  83. package/src/collections/cms-vals.spec.js +66 -0
  84. package/src/collections/deck-version-screenshots.js +0 -22
  85. package/src/collections/scenarios.js +18 -0
  86. package/src/collections.js +1 -2
  87. package/src/fixtures.js +17 -1
  88. package/src/middlewares/base.js +1 -2
  89. package/src/models/appointment.js +32 -6
  90. package/src/models/auto-adjunct.js +3 -2
  91. package/src/models/base.js +3 -2
  92. package/src/models/cms-val.js +3 -3
  93. package/src/models/customer.js +1 -0
  94. package/src/models/deck-layout.js +54 -0
  95. package/src/models/deck-version-screenshot.js +2 -2
  96. package/src/models/deck-version.js +12 -14
  97. package/src/models/image.js +0 -3
  98. package/src/models/pack-diff.js +14 -9
  99. package/src/models/preset.js +8 -6
  100. package/src/models/scenario.js +39 -0
  101. package/src/models/user.js +8 -1
  102. package/src/models.js +2 -0
  103. package/src/presentation/appointment-presentation.js +7 -4
  104. package/src/presentation/base-presentation-model.js +29 -23
  105. package/src/presentation/base-presentation-model.spec.js +22 -22
  106. package/src/presentation/presentation-deck.js +6 -0
  107. package/src/presentation/presentation-section.js +26 -1
  108. package/src/presentation/presentation-section.spec.js +14 -1
  109. package/src/presentation/presentation-slide.js +24 -0
  110. package/src/presentation/presentation-slide.spec.js +7 -0
  111. package/src/sync.js +16 -12
  112. package/src/utils.js +13 -3
  113. package/src/utils.spec.js +27 -0
  114. package/cjs/collections/created-assets.js +0 -26
  115. package/cjs/collections/created-assets.js.map +0 -1
  116. package/cjs/collections/deleted-assets.js +0 -26
  117. package/cjs/collections/deleted-assets.js.map +0 -1
  118. package/src/collections/created-assets.js +0 -26
  119. package/src/collections/deleted-assets.js +0 -26
@@ -1 +1 @@
1
- {"version":3,"file":"utils.spec.js","names":["_utils","require","describe","test","url","expect","getShortURL","toEqual","testString","removeMultiByteChars","testString2","testString3","it","actual","getHostname","toThrow","replaceHostname","data","expected","beforeURL","afterURL","first","anArray","nestedObject","second"],"sources":["../src/utils.spec.js"],"sourcesContent":["import {\n\tgetHostname,\n\tgetShortURL,\n\tremoveMultiByteChars,\n\treplaceHostname,\n} from \"./utils.js\";\n\ndescribe(\"getShortURL()\", () => {\n\ttest(\"shorten a full url to a short one\", () => {\n\t\tconst url = \"http://client.salespreso.com/api/users/1/\";\n\t\texpect(getShortURL(url)).toEqual(\"/api/users/1/\");\n\t});\n\n\ttest(\"not break an already short url\", () => {\n\t\tconst url = \"/api/users/1/\";\n\t\texpect(getShortURL(url)).toEqual(\"/api/users/1/\");\n\t});\n});\n\ndescribe(\"removeMultiByteChars()\", () => {\n\ttest(\"correctly strip offending multibyte characters from string\", () => {\n\t\tconst testString = \"SUZI LUCK’S CANTEEN & COCKTAIL BAR\";\n\t\texpect(removeMultiByteChars(testString)).toEqual(\n\t\t\t\"SUZI LUCKS CANTEEN & COCKTAIL BAR\",\n\t\t);\n\t});\n\n\ttest(\"sanitize urls correctly\", () => {\n\t\tconst testString = \"http://client.salespreso.com/api/users/1/’\";\n\t\tconst testString2 = \"/api/users/1/’\";\n\t\tconst testString3 = \"/api/users/1/?param=1&test=3&_r=4\";\n\t\texpect(removeMultiByteChars(testString)).toEqual(\n\t\t\t\"http://client.salespreso.com/api/users/1/\",\n\t\t);\n\t\texpect(removeMultiByteChars(testString2)).toEqual(\"/api/users/1/\");\n\t\texpect(removeMultiByteChars(testString3)).toEqual(\n\t\t\t\"/api/users/1/?param=1&test=3&_r=4\",\n\t\t);\n\t});\n});\n\ndescribe(\"getHostname()\", () => {\n\tit(\"throws an error if hostname isn't a string\", () => {\n\t\tconst actual = () => getHostname(null);\n\t\texpect(actual).toThrow();\n\t});\n\n\tit(\"returns a hostname from a full URL\", () => {\n\t\tconst actual = getHostname(\"https://www.horse.com/api/horses/1/\");\n\t\texpect(actual).toEqual(\"www.horse.com\");\n\t});\n\n\tit(\"returns a hostname from just the domain\", () => {\n\t\tconst actual = getHostname(\"https://www.horse.com/\");\n\t\texpect(actual).toEqual(\"www.horse.com\");\n\t});\n\n\tit(\"just returns the hostname\", () => {\n\t\tconst actual = getHostname(\"www.horse.com\");\n\t\texpect(actual).toEqual(\"www.horse.com\");\n\t});\n});\n\ndescribe(\"replaceHostname()\", () => {\n\tit(\"throws an error if not from hostname\", () => {\n\t\tconst actual = () => replaceHostname(\"foo\", null, \"brand.new.com\");\n\t\texpect(actual).toThrow();\n\t});\n\n\tit(\"throws an error if not to hostname\", () => {\n\t\tconst actual = () => replaceHostname(\"foo\", \"old.url.com\", null);\n\t\texpect(actual).toThrow();\n\t});\n\n\tit(\"replaces hostname of a string\", () => {\n\t\tconst data = \"https://old.url.com/api/appointments/1/\";\n\t\tconst expected = \"https://brand.new.com/api/appointments/1/\";\n\t\tconst actual = replaceHostname(data, \"old.url.com\", \"brand.new.com\");\n\t\texpect(actual).toEqual(expected);\n\t});\n\n\tit(\"takes into account the protocol\", () => {\n\t\tconst data = \"http://old.url.com/api/appointments/1/\";\n\t\tconst expected = \"http://brand.new.com/api/appointments/1/\";\n\t\tconst actual = replaceHostname(\n\t\t\tdata,\n\t\t\t\"https://old.url.com/\",\n\t\t\t\"https://brand.new.com/\",\n\t\t);\n\t\texpect(actual).toEqual(expected);\n\t});\n\n\tit(\"replaces hostnames in an array\", () => {\n\t\tconst data = [\n\t\t\t\"https://old.url.com/api/appointments/1/\",\n\t\t\t\"https://old.url.com/api/foo/1/bars/1/\",\n\t\t];\n\t\tconst expected = [\n\t\t\t\"https://brand.new.com/api/appointments/1/\",\n\t\t\t\"https://brand.new.com/api/foo/1/bars/1/\",\n\t\t];\n\t\tconst actual = replaceHostname(data, \"old.url.com\", \"brand.new.com\");\n\t\texpect(actual).toEqual(expected);\n\t});\n\n\tit(\"replaces hostnames in an object\", () => {\n\t\tconst data = {\n\t\t\turl: \"https://old.url.com/api/appointments/1/\",\n\t\t};\n\t\tconst expected = {\n\t\t\turl: \"https://brand.new.com/api/appointments/1/\",\n\t\t};\n\n\t\tconst actual = replaceHostname(data, \"old.url.com\", \"brand.new.com\");\n\t\texpect(actual).toEqual(expected);\n\t});\n\n\tit(\"hostnames not related aren't affected\", () => {\n\t\tconst data = {\n\t\t\turl: \"https://some.otherurl.com/helloworld/\",\n\t\t};\n\t\tconst expected = {\n\t\t\turl: \"https://some.otherurl.com/helloworld/\",\n\t\t};\n\n\t\tconst actual = replaceHostname(data, \"old.url.com\", \"brand.new.com\");\n\t\texpect(actual).toEqual(expected);\n\t});\n\n\tit(\"updates data that is nested\", () => {\n\t\tconst beforeURL = \"https://old.url.com/api/appointments/1/\";\n\t\tconst afterURL = \"https://some.otherurl.com/api/appointments/1/\";\n\n\t\tconst data = {\n\t\t\tfirst: beforeURL,\n\t\t\tanArray: [beforeURL, beforeURL],\n\t\t\tnestedObject: {\n\t\t\t\tfirst: beforeURL,\n\t\t\t\tsecond: beforeURL,\n\t\t\t},\n\t\t};\n\n\t\tconst expected = {\n\t\t\tfirst: afterURL,\n\t\t\tanArray: [afterURL, afterURL],\n\t\t\tnestedObject: {\n\t\t\t\tfirst: afterURL,\n\t\t\t\tsecond: afterURL,\n\t\t\t},\n\t\t};\n\n\t\tconst actual = replaceHostname(data, \"old.url.com\", \"some.otherurl.com\");\n\t\texpect(actual).toEqual(expected);\n\t});\n\n\tit(\"does not affect hostname within a string\", () => {\n\t\tconst data = \"room:old.url.com:123\";\n\t\tconst expected = \"room:old.url.com:123\";\n\t\tconst actual = replaceHostname(data, \"old.url.com\", \"some.otherurl.com\");\n\t\texpect(actual).toEqual(expected);\n\t});\n});\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"utils.spec.js","names":["_utils","require","describe","test","url","expect","getShortURL","toEqual","testString","removeMultiByteChars","testString2","testString3","it","actual","getHostname","toThrow","replaceHostname","data","expected","beforeURL","afterURL","first","anArray","nestedObject","second","only","forEach","base64","sanitizeBase64","foo"],"sources":["../src/utils.spec.js"],"sourcesContent":["import {\n\tgetHostname,\n\tgetShortURL,\n\tremoveMultiByteChars,\n\treplaceHostname,\n\tsanitizeBase64,\n} from \"./utils.js\";\n\ndescribe(\"getShortURL()\", () => {\n\ttest(\"shorten a full url to a short one\", () => {\n\t\tconst url = \"http://client.salespreso.com/api/users/1/\";\n\t\texpect(getShortURL(url)).toEqual(\"/api/users/1/\");\n\t});\n\n\ttest(\"not break an already short url\", () => {\n\t\tconst url = \"/api/users/1/\";\n\t\texpect(getShortURL(url)).toEqual(\"/api/users/1/\");\n\t});\n});\n\ndescribe(\"removeMultiByteChars()\", () => {\n\ttest(\"correctly strip offending multibyte characters from string\", () => {\n\t\tconst testString = \"SUZI LUCK’S CANTEEN & COCKTAIL BAR\";\n\t\texpect(removeMultiByteChars(testString)).toEqual(\n\t\t\t\"SUZI LUCKS CANTEEN & COCKTAIL BAR\",\n\t\t);\n\t});\n\n\ttest(\"sanitize urls correctly\", () => {\n\t\tconst testString = \"http://client.salespreso.com/api/users/1/’\";\n\t\tconst testString2 = \"/api/users/1/’\";\n\t\tconst testString3 = \"/api/users/1/?param=1&test=3&_r=4\";\n\t\texpect(removeMultiByteChars(testString)).toEqual(\n\t\t\t\"http://client.salespreso.com/api/users/1/\",\n\t\t);\n\t\texpect(removeMultiByteChars(testString2)).toEqual(\"/api/users/1/\");\n\t\texpect(removeMultiByteChars(testString3)).toEqual(\n\t\t\t\"/api/users/1/?param=1&test=3&_r=4\",\n\t\t);\n\t});\n});\n\ndescribe(\"getHostname()\", () => {\n\tit(\"throws an error if hostname isn't a string\", () => {\n\t\tconst actual = () => getHostname(null);\n\t\texpect(actual).toThrow();\n\t});\n\n\tit(\"returns a hostname from a full URL\", () => {\n\t\tconst actual = getHostname(\"https://www.horse.com/api/horses/1/\");\n\t\texpect(actual).toEqual(\"www.horse.com\");\n\t});\n\n\tit(\"returns a hostname from just the domain\", () => {\n\t\tconst actual = getHostname(\"https://www.horse.com/\");\n\t\texpect(actual).toEqual(\"www.horse.com\");\n\t});\n\n\tit(\"just returns the hostname\", () => {\n\t\tconst actual = getHostname(\"www.horse.com\");\n\t\texpect(actual).toEqual(\"www.horse.com\");\n\t});\n});\n\ndescribe(\"replaceHostname()\", () => {\n\tit(\"throws an error if not from hostname\", () => {\n\t\tconst actual = () => replaceHostname(\"foo\", null, \"brand.new.com\");\n\t\texpect(actual).toThrow();\n\t});\n\n\tit(\"throws an error if not to hostname\", () => {\n\t\tconst actual = () => replaceHostname(\"foo\", \"old.url.com\", null);\n\t\texpect(actual).toThrow();\n\t});\n\n\tit(\"replaces hostname of a string\", () => {\n\t\tconst data = \"https://old.url.com/api/appointments/1/\";\n\t\tconst expected = \"https://brand.new.com/api/appointments/1/\";\n\t\tconst actual = replaceHostname(data, \"old.url.com\", \"brand.new.com\");\n\t\texpect(actual).toEqual(expected);\n\t});\n\n\tit(\"takes into account the protocol\", () => {\n\t\tconst data = \"http://old.url.com/api/appointments/1/\";\n\t\tconst expected = \"http://brand.new.com/api/appointments/1/\";\n\t\tconst actual = replaceHostname(\n\t\t\tdata,\n\t\t\t\"https://old.url.com/\",\n\t\t\t\"https://brand.new.com/\",\n\t\t);\n\t\texpect(actual).toEqual(expected);\n\t});\n\n\tit(\"replaces hostnames in an array\", () => {\n\t\tconst data = [\n\t\t\t\"https://old.url.com/api/appointments/1/\",\n\t\t\t\"https://old.url.com/api/foo/1/bars/1/\",\n\t\t];\n\t\tconst expected = [\n\t\t\t\"https://brand.new.com/api/appointments/1/\",\n\t\t\t\"https://brand.new.com/api/foo/1/bars/1/\",\n\t\t];\n\t\tconst actual = replaceHostname(data, \"old.url.com\", \"brand.new.com\");\n\t\texpect(actual).toEqual(expected);\n\t});\n\n\tit(\"replaces hostnames in an object\", () => {\n\t\tconst data = {\n\t\t\turl: \"https://old.url.com/api/appointments/1/\",\n\t\t};\n\t\tconst expected = {\n\t\t\turl: \"https://brand.new.com/api/appointments/1/\",\n\t\t};\n\n\t\tconst actual = replaceHostname(data, \"old.url.com\", \"brand.new.com\");\n\t\texpect(actual).toEqual(expected);\n\t});\n\n\tit(\"hostnames not related aren't affected\", () => {\n\t\tconst data = {\n\t\t\turl: \"https://some.otherurl.com/helloworld/\",\n\t\t};\n\t\tconst expected = {\n\t\t\turl: \"https://some.otherurl.com/helloworld/\",\n\t\t};\n\n\t\tconst actual = replaceHostname(data, \"old.url.com\", \"brand.new.com\");\n\t\texpect(actual).toEqual(expected);\n\t});\n\n\tit(\"updates data that is nested\", () => {\n\t\tconst beforeURL = \"https://old.url.com/api/appointments/1/\";\n\t\tconst afterURL = \"https://some.otherurl.com/api/appointments/1/\";\n\n\t\tconst data = {\n\t\t\tfirst: beforeURL,\n\t\t\tanArray: [beforeURL, beforeURL],\n\t\t\tnestedObject: {\n\t\t\t\tfirst: beforeURL,\n\t\t\t\tsecond: beforeURL,\n\t\t\t},\n\t\t};\n\n\t\tconst expected = {\n\t\t\tfirst: afterURL,\n\t\t\tanArray: [afterURL, afterURL],\n\t\t\tnestedObject: {\n\t\t\t\tfirst: afterURL,\n\t\t\t\tsecond: afterURL,\n\t\t\t},\n\t\t};\n\n\t\tconst actual = replaceHostname(data, \"old.url.com\", \"some.otherurl.com\");\n\t\texpect(actual).toEqual(expected);\n\t});\n\n\tit(\"does not affect hostname within a string\", () => {\n\t\tconst data = \"room:old.url.com:123\";\n\t\tconst expected = \"room:old.url.com:123\";\n\t\tconst actual = replaceHostname(data, \"old.url.com\", \"some.otherurl.com\");\n\t\texpect(actual).toEqual(expected);\n\t});\n});\n\ndescribe.only(\"sanitizeBase64()\", () => {\n\t[\"data:image/webp;base64,\", \"data%3Aimage%2Fwebp%3Bbase64%2C\"].forEach(\n\t\t(base64) => {\n\t\t\tit(\"should strip base64 from string\", () => {\n\t\t\t\texpect(sanitizeBase64(base64)).toEqual(\"\");\n\t\t\t});\n\n\t\t\tit(\"should strip base64 from array\", () => {\n\t\t\t\texpect(sanitizeBase64([base64])).toEqual([\"\"]);\n\t\t\t});\n\n\t\t\tit(\"should strip base64 from nested object\", () => {\n\t\t\t\texpect(\n\t\t\t\t\tsanitizeBase64({\n\t\t\t\t\t\tfoo: [base64],\n\t\t\t\t\t}),\n\t\t\t\t).toEqual({ foo: [\"\"] });\n\t\t\t});\n\n\t\t\tit(\"should not strip if condition says not to\", () => {\n\t\t\t\texpect(sanitizeBase64(base64, () => false)).toEqual(base64);\n\t\t\t});\n\t\t},\n\t);\n});\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@livepreso/api",
3
3
  "license": "UNLICENSED",
4
- "version": "6.53.1",
4
+ "version": "6.55.0",
5
5
  "description": "Everything to do with talking to the SalePreso API",
6
6
  "main": "index.js",
7
7
  "module": "esm/index.js",
@@ -1,3 +1,3 @@
1
- Browserslist: browsers data (caniuse-lite) is 8 months old. Please run:
1
+ Browserslist: browsers data (caniuse-lite) is 9 months old. Please run:
2
2
  npx update-browserslist-db@latest
3
3
  Why you should do it regularly: https://github.com/browserslist/update-db#readme
@@ -3,7 +3,7 @@ Invoking: run-p build:*
3
3
  > @livepreso/api@6.53.0 build:cjs
4
4
  > BABEL_ENV=cjs babel --delete-dir-on-start src/ --out-dir=cjs/ -s
5
5
 
6
- Browserslist: browsers data (caniuse-lite) is 8 months old. Please run:
6
+ Browserslist: browsers data (caniuse-lite) is 9 months old. Please run:
7
7
  npx update-browserslist-db@latest
8
8
  Why you should do it regularly: https://github.com/browserslist/update-db#readme
9
- Successfully compiled 163 files with Babel (3818ms).
9
+ Successfully compiled 163 files with Babel (17903ms).
package/src/api.js CHANGED
@@ -20,7 +20,7 @@ export const Api = {
20
20
  * @memberof api.Api
21
21
  * @prop {number} version
22
22
  */
23
- version: 32,
23
+ version: 33,
24
24
 
25
25
  /**
26
26
  * Initialize the api. Connects to the network and returns the
@@ -1,6 +1,5 @@
1
1
  import "../models/auto-adjunct.js";
2
2
 
3
- import Auth from "../auth.js";
4
3
  import { BaseCollection } from "./base.js";
5
4
  import { register } from "../state-register.js";
6
5
 
@@ -23,27 +22,6 @@ export const AutoAdjunctCollection = BaseCollection.extend(
23
22
  },
24
23
  });
25
24
  },
26
-
27
- fetch(opts = {}) {
28
- const { user } = Auth;
29
-
30
- if (!opts.data) {
31
- opts.data = {};
32
- }
33
-
34
- // Let's only add this if it's not already being set, in case a global user
35
- // DOES want to see a specific team.
36
- if (!opts.data.team) {
37
- //
38
- // Filter all global autoadjuncts, and only query teams that
39
- // the authorized user is a part of. This is mostly for the case where
40
- // a 'global' temp slide admin could end up seeing autoadjuncts for
41
- // many teams - which would be increadibly confusing.
42
- opts.data.team = [null].concat(user.team_set.map((team) => team.id));
43
- }
44
-
45
- return BaseCollection.prototype.fetch.call(this, opts);
46
- },
47
25
  },
48
26
  );
49
27
 
@@ -1,3 +1,4 @@
1
+ import _ from "lodash";
1
2
  import "../models/cms-val.js";
2
3
 
3
4
  import Auth from "../auth.js";
@@ -43,4 +44,31 @@ export const CMSValCollection = BaseCollection.extend(
43
44
 
44
45
  CMSValCollection.canBeEmpty = true;
45
46
 
47
+ CMSValCollection.getPrioritized = (cmsVals, tenancy = Auth.user.tenancy) => {
48
+ const cmsValsGroupedBySlides = _.groupBy(cmsVals, "key");
49
+
50
+ return _.map(cmsValsGroupedBySlides, (group) => {
51
+ const scenarioCmsVal = group.find((cmsValue) => !!cmsValue.scenario);
52
+
53
+ // The first cms val owned by the tenancy you're in
54
+ const tenancyStandardDeckCmsVal = group.find(
55
+ (cmsValue) =>
56
+ !cmsValue.scenario && cmsValue._tenancy?.owner_id === tenancy.id,
57
+ );
58
+
59
+ // The first cms val owned by the parent tenancy.
60
+ const parentTenancyStandardDeckCmsVal = group.find(
61
+ (cmsValue) =>
62
+ !cmsValue.scenario && cmsValue._tenancy?.owner_id !== tenancy.id,
63
+ );
64
+
65
+ // Order of preference: Scenario > Tenancy > Parent Tenancy
66
+ return (
67
+ scenarioCmsVal ||
68
+ tenancyStandardDeckCmsVal ||
69
+ parentTenancyStandardDeckCmsVal
70
+ );
71
+ });
72
+ };
73
+
46
74
  register("CMSValCollection", CMSValCollection);
@@ -0,0 +1,66 @@
1
+ import { CMSValCollection } from "./cms-vals.js";
2
+
3
+ const childTenancy = { id: "66d7572f-85f6-4552-879a-25cf05ae311f" };
4
+ const parentTenancy = { id: "cf5ad5a5-d149-42b4-b09b-e52b7afdf507" };
5
+ const testScenarioURL =
6
+ "http://my/api/scenario/362bddc7-1821-4f43-921c-244e5c3175f7/";
7
+
8
+ describe("#.getPrioritized", () => {
9
+ const scenarioCmsVal = {
10
+ id: 1,
11
+ key: "foo",
12
+ value: "Scenario",
13
+ scenario: testScenarioURL,
14
+ _tenancy: { owner_id: childTenancy.id },
15
+ };
16
+
17
+ const tenancyCmsVal = {
18
+ id: 2,
19
+ key: "foo",
20
+ value: "Tenancy",
21
+ scenario: testScenarioURL,
22
+ _tenancy: { owner_id: childTenancy.id },
23
+ };
24
+
25
+ const parentTenancyCmsVal = {
26
+ id: 3,
27
+ key: "foo",
28
+ value: "Parent Tenancy",
29
+ scenario: testScenarioURL,
30
+ _tenancy: { owner_id: parentTenancy.id },
31
+ };
32
+
33
+ const testFn = (cmsvals, tenancy) =>
34
+ CMSValCollection.getPrioritized(cmsvals, tenancy).filter(
35
+ (c) => c.key === "foo",
36
+ );
37
+
38
+ it("prefer scenario cmsval over others", () => {
39
+ const cmsvals = [scenarioCmsVal, tenancyCmsVal, parentTenancyCmsVal];
40
+ const results = testFn(cmsvals, childTenancy);
41
+ expect(results).toHaveLength(1);
42
+ expect(results[0].value).toEqual("Scenario");
43
+ });
44
+
45
+ it("prefer tenancy cmsval over others", () => {
46
+ const cmsvals = [
47
+ { ...scenarioCmsVal, key: "bar" },
48
+ tenancyCmsVal,
49
+ parentTenancyCmsVal,
50
+ ];
51
+ const results = testFn(cmsvals, childTenancy);
52
+ expect(results).toHaveLength(1);
53
+ expect(results[0].value).toEqual("Tenancy");
54
+ });
55
+
56
+ it("prefer global tenancy cmsval over others", () => {
57
+ const cmsvals = [
58
+ { ...scenarioCmsVal, key: "bar" },
59
+ { ...tenancyCmsVal, key: "baz" },
60
+ parentTenancyCmsVal,
61
+ ];
62
+ const results = testFn(cmsvals, childTenancy);
63
+ expect(results).toHaveLength(1);
64
+ expect(results[0].value).toEqual("Parent Tenancy");
65
+ });
66
+ });
@@ -1,6 +1,5 @@
1
1
  import "../models/deck-version-screenshot.js";
2
2
 
3
- import Auth from "../auth.js";
4
3
  import { BaseCollection } from "./base.js";
5
4
  import { register } from "../state-register.js";
6
5
 
@@ -14,27 +13,6 @@ export const DeckVersionScreenshotCollection = BaseCollection.extend(
14
13
  /** @lends collections.DeckVersionScreenshotCollection# */ {
15
14
  model: "DeckVersionScreenshotModel",
16
15
 
17
- fetch(opts = {}) {
18
- const { user } = Auth;
19
-
20
- if (!opts.data) {
21
- opts.data = {};
22
- }
23
-
24
- // Let's only add this if it's not already being set, in case a global user
25
- // DOES want to see a specific team.
26
- if (user && !opts.data.team) {
27
- //
28
- // Filter all global autoadjuncts, and only query teams that
29
- // the authorized user is a part of. This is mostly for the case where
30
- // a 'global' temp slide admin could end up seeing autoadjuncts for
31
- // many teams - which would be increadibly confusing.
32
- opts.data.team = [null].concat(user.team_set.map((team) => team.id));
33
- }
34
-
35
- return BaseCollection.prototype.fetch.call(this, opts);
36
- },
37
-
38
16
  url() {
39
17
  if (!this._url && this.parent) {
40
18
  this._options.deckversion = this.parent;
@@ -0,0 +1,18 @@
1
+ import "../models/scenario.js";
2
+
3
+ import { BaseCollection } from "./base.js";
4
+ import { register } from "../state-register.js";
5
+
6
+ /**
7
+ * @constructor
8
+ * @alias collections.ScenarioCollection
9
+ * @extends collections.BaseCollection
10
+ * @see models.ScenarioModel
11
+ */
12
+ export const ScenarioCollection = BaseCollection.extend(
13
+ /** @lends collections.ScenarioCollection# */ {
14
+ model: "ScenarioModel",
15
+ },
16
+ );
17
+
18
+ register("ScenarioCollection", ScenarioCollection);
@@ -12,12 +12,10 @@ export * from "./collections/base";
12
12
  export * from "./collections/cms-vals";
13
13
  export * from "./collections/contacts";
14
14
  export * from "./collections/contact-phones";
15
- export * from "./collections/created-assets";
16
15
  export * from "./collections/customers";
17
16
  export * from "./collections/deck-versions";
18
17
  export * from "./collections/deck-version-screenshots";
19
18
  export * from "./collections/decks";
20
- export * from "./collections/deleted-assets";
21
19
  export * from "./collections/dispatches";
22
20
  export * from "./collections/events";
23
21
  export * from "./collections/event-objects";
@@ -26,6 +24,7 @@ export * from "./collections/opportunities";
26
24
  export * from "./collections/pack-diffs";
27
25
  export * from "./collections/packs";
28
26
  export * from "./collections/presets";
27
+ export * from "./collections/scenarios";
29
28
  export * from "./collections/section-selections";
30
29
  export * from "./collections/sections";
31
30
  export * from "./collections/signing-backends";
package/src/fixtures.js CHANGED
@@ -22,8 +22,24 @@ const presentationCollections = {
22
22
  PresentationSubSlides: presentation.PresentationSubSlides,
23
23
  };
24
24
 
25
+ function uuid() {
26
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
27
+ const r = (Math.random() * 16) | 0;
28
+ const v = c === "x" ? r : (r & 0x3) | 0x8;
29
+ return v.toString(16);
30
+ });
31
+ }
32
+
25
33
  function makeFactory(name, Model, ignoreFields = []) {
26
- const factory = Factory.define(name, Model).sequence("id");
34
+ const factory = Factory.define(name, Model);
35
+ const { detailType } = Model.prototype;
36
+ if (detailType === "string" || detailType === "number") {
37
+ factory.sequence("id");
38
+ } else if (detailType === "uuid") {
39
+ factory.attr("id", () => uuid());
40
+ } else {
41
+ throw new Error("Unknown detailType " + detailType);
42
+ }
27
43
 
28
44
  const { _definition: definition, _children: children } = Model.prototype;
29
45
 
@@ -1,6 +1,5 @@
1
- /* eslint-disable */
2
1
  export default class BaseMiddleware {
3
- preflight(request, model) {
2
+ preflight(request, model, options) {
4
3
  return request;
5
4
  }
6
5
 
@@ -3,6 +3,7 @@ import "./snapshot.js";
3
3
  import "./feed-data.js";
4
4
  import "./preset.js";
5
5
  import "./team.js";
6
+ import "./scenario.js";
6
7
  import "./hosted-preso.js";
7
8
  import "./appointment-stats.js";
8
9
  import "./appointment-tags.js";
@@ -122,6 +123,8 @@ export const AppointmentModel = BaseModel.extend(
122
123
  * @property {models.SnapshotModel} latest_snapshot
123
124
  * @property {models.UserModel} user
124
125
  * @property {models.AppointmentStatsModel} appointmentStats
126
+ * @property {models.ScenarioModel} scenario
127
+ * @property {models.TeamModel} team_branding
125
128
  */
126
129
  children: {
127
130
  preset: "PresetModel",
@@ -130,7 +133,8 @@ export const AppointmentModel = BaseModel.extend(
130
133
  user: "UserModel",
131
134
  latest_tele: "HostedPresoModel",
132
135
  stats: "AppointmentStatsModel",
133
- team: "TeamModel",
136
+ scenario: "ScenarioModel",
137
+ team_branding: "TeamModel",
134
138
  },
135
139
 
136
140
  /**
@@ -273,6 +277,14 @@ export const AppointmentModel = BaseModel.extend(
273
277
  this.adjunctSubSlides?.fetch(fetchOptions),
274
278
  this.contact_set?.fetchSet(fetchOptions),
275
279
  this.tags?.fetch(fetchOptions),
280
+ this.team_branding?.fetch(fetchOptions),
281
+ this.scenario?.fetch(fetchOptions)?.catch((e) => {
282
+ if (e.status === 404) {
283
+ this.scenario = null;
284
+ return;
285
+ }
286
+ throw e;
287
+ }),
276
288
  this.user?.fetch(fetchOptions)?.catch((e) => {
277
289
  if (e.status && e.status === 404) {
278
290
  // It's possible for a user to be deactivated, which means they'll
@@ -318,16 +330,29 @@ export const AppointmentModel = BaseModel.extend(
318
330
  return Promise.all(fetches);
319
331
  })
320
332
  .then(() => {
321
- return Promise.all(
322
- this.deckversion_set.map((model) => {
333
+ const scenarioID = this.scenario?.id ?? null;
334
+ const scenarioFilter = [null];
335
+ if (scenarioID) {
336
+ scenarioFilter.push(scenarioID);
337
+ }
338
+
339
+ return Promise.all([
340
+ this.scenario?.owner_team?.fetch?.(fetchOptions),
341
+ ...this.deckversion_set.map((model) => {
323
342
  return Promise.all([
324
- model.screenshots.fetch(fetchOptions),
343
+ model.screenshots.fetch(
344
+ _.merge(fetchOptions, {
345
+ data: {
346
+ scenario: scenarioFilter,
347
+ },
348
+ }),
349
+ ),
325
350
  model.template_set.fetchSet(fetchOptions),
326
351
  model.manifest_json.fetch(fetchOptions),
327
352
  model.deck.fetch(fetchOptions),
328
353
  ]);
329
354
  }),
330
- );
355
+ ]);
331
356
  })
332
357
  .then(() => {
333
358
  const deckversionTemplates =
@@ -385,7 +410,8 @@ export const AppointmentModel = BaseModel.extend(
385
410
  no_edit_after: appointment.no_edit_after,
386
411
  no_share_after: appointment.no_share_after,
387
412
  no_delete_after: appointment.no_delete_after,
388
- team: this._retrieveURL(appointment.team),
413
+ scenario: this._retrieveURL(appointment.scenario),
414
+ team_branding: this._retrieveURL(appointment.team_branding),
389
415
  editors_can_change_editors: appointment.editors_can_change_editors,
390
416
  share_visibility_mode: appointment.share_visibility_mode,
391
417
  };
@@ -1,5 +1,5 @@
1
1
  import "./template.js";
2
- import "./team.js";
2
+ import "./scenario.js";
3
3
  import "./deck.js";
4
4
 
5
5
  import { BaseModel } from "./base.js";
@@ -49,11 +49,12 @@ export const AutoAdjunctModel = BaseModel.extend(
49
49
  /**
50
50
  * @property {models.DeckModel} deck
51
51
  * @property {models.TemplateModel} template
52
+ * @property {models.ScenarioModel} scenario
52
53
  */
53
54
  children: {
54
55
  deck: "DeckModel",
55
56
  template: "TemplateModel",
56
- team: "TeamModel",
57
+ scenario: "ScenarioModel",
57
58
  },
58
59
  },
59
60
  );
@@ -259,8 +259,9 @@ export const BaseModel = Model.extend(
259
259
  }
260
260
 
261
261
  const idStr = urlEnd.split(resourceEnd).join("");
262
-
263
- if ((idStr.match(/\//g) || []).length === 1) {
262
+ if (this.detailType === "uuid") {
263
+ return idStr.slice(0, -1);
264
+ } else if ((idStr.match(/\//g) || []).length === 1) {
264
265
  return parseInt(idStr.slice(0, -1), 10);
265
266
  }
266
267
 
@@ -1,5 +1,5 @@
1
1
  import "./user.js";
2
- import "./team.js";
2
+ import "./scenario.js";
3
3
  import "./deck.js";
4
4
 
5
5
  import { BaseModel } from "../models/base.js";
@@ -28,12 +28,12 @@ export const CMSValModel = BaseModel.extend(
28
28
  /**
29
29
  * @property {models.UserModel} user
30
30
  * @property {models.DeckModel} deck
31
- * @property {models.TeamModel} team
31
+ * @property {models.ScenarioModel} scenario
32
32
  */
33
33
  children: {
34
34
  user: "UserModel",
35
35
  deck: "DeckModel",
36
- team: "TeamModel",
36
+ scenario: "ScenarioModel",
37
37
  },
38
38
 
39
39
  url() {
@@ -133,6 +133,7 @@ export const CustomerModel = BaseModel.extend(
133
133
  title: this.title,
134
134
  website: this.website,
135
135
  team_set: this._retrieveURL(this.team_set),
136
+ logo_original: this.logo_original,
136
137
  };
137
138
 
138
139
  if (this.id) {
@@ -0,0 +1,54 @@
1
+ import { BaseModel } from "./base.js";
2
+ import { register } from "../state-register.js";
3
+
4
+ /**
5
+ * @constructor
6
+ * @alias models.DeckLayoutModel
7
+ * @extends models.BaseModel
8
+ */
9
+ export const DeckLayoutModel = BaseModel.extend(
10
+ /** @lends models.DeckLayoutModel# */ {
11
+ modelName: "deck-layout",
12
+
13
+ props: {
14
+ items: "object",
15
+ },
16
+
17
+ fetch(opts) {
18
+ return BaseModel.prototype.fetch.call(this, opts).tap((tags) => {
19
+ this.items = tags;
20
+ });
21
+ },
22
+
23
+ toJSON() {
24
+ return this.items;
25
+ },
26
+
27
+ toServer() {
28
+ return this.items;
29
+ },
30
+
31
+ save() {
32
+ return BaseModel.prototype.save.call(this).tap((tags) => {
33
+ this.items = tags;
34
+ });
35
+ },
36
+
37
+ getPlainURL() {
38
+ const _url = BaseModel.prototype.getPlainURL.call(this);
39
+
40
+ // Because the URL has {id} in it, the matcher replaces the deck id
41
+ // with the value but also automatically adds it as a detail ID (which
42
+ // doesn't make sense here). We strip the extra ID off here.
43
+ //
44
+ // Ie the default plain URL would look like:
45
+ // /api/decks/{id}/layout/{id}/ and this splitting gives us the correct
46
+ // /api/decks/{id}/layout/ instead.
47
+ return _url.split("/").slice(0, -2).concat([""]).join("/");
48
+ },
49
+ },
50
+ );
51
+
52
+ DeckLayoutModel.canBeEmpty = true;
53
+
54
+ register("DeckLayoutModel", DeckLayoutModel);
@@ -1,4 +1,4 @@
1
- import "./team.js";
1
+ import "./scenario.js";
2
2
 
3
3
  import { BaseModel } from "./base.js";
4
4
  import _ from "lodash";
@@ -35,7 +35,7 @@ export const DeckVersionScreenshotModel = BaseModel.extend(
35
35
  },
36
36
 
37
37
  children: {
38
- team: "TeamModel",
38
+ scenario: "ScenarioModel",
39
39
  },
40
40
 
41
41
  serialize() {
@@ -7,6 +7,7 @@ import "./manifest-json.js";
7
7
 
8
8
  import { Auth } from "../auth.js";
9
9
  import { BaseModel } from "./base.js";
10
+ import { DeckLayoutModel } from "./deck-layout.js";
10
11
  import { DeckVersionScreenshotCollection } from "../collections/deck-version-screenshots.js";
11
12
  import Promise from "bluebird";
12
13
  import { TemplateCollection } from "../collections.js";
@@ -225,31 +226,28 @@ export const DeckVersionModel = BaseModel.extend(
225
226
  );
226
227
  },
227
228
 
228
- fetchLayout: function (presetId, teamIds) {
229
+ fetchLayout: async function (presetId, scenarioID) {
229
230
  let queryParams = { version: this.version };
230
231
  if (presetId) {
231
232
  queryParams.preset_id = presetId;
232
233
  }
233
- if (teamIds) {
234
- queryParams.team_id = teamIds;
234
+ if (scenarioID) {
235
+ queryParams.scenario_id = scenarioID;
235
236
  }
236
237
 
237
238
  if (!this.id) {
238
239
  return Promise.reject(new Error("DeckVersion has no ID."));
239
240
  }
240
241
 
241
- const path = `${this.deck.url()}layout/`;
242
+ const layout = new DeckLayoutModel(
243
+ { id: this.deck.id },
244
+ {
245
+ data: queryParams,
246
+ },
247
+ );
248
+ await layout.fetch();
242
249
 
243
- return superagent
244
- .get(path)
245
- .set(Auth.headers)
246
- .query(queryParams)
247
- .then((res) => {
248
- if (!res.ok) {
249
- return Promise.reject(res);
250
- }
251
- return res.body;
252
- });
250
+ return layout.toJSON();
253
251
  },
254
252
 
255
253
  toServer() {
@@ -50,9 +50,6 @@ export const ImageModel = BaseModel.extend(
50
50
  })
51
51
  .then((blob) => {
52
52
  const file = new File([blob], `image.${fileEnd}`, { type: fileType });
53
- const formData = new FormData();
54
- formData.append("image_original", file);
55
-
56
53
  return this.uploadFile(file);
57
54
  });
58
55
  },
@@ -1,6 +1,5 @@
1
1
  import "./pack.js";
2
- import "../collections/created-assets.js";
3
- import "../collections/deleted-assets.js";
2
+ import { AssetCollection } from "../collections.js";
4
3
 
5
4
  import { BaseModel } from "./base.js";
6
5
  import { register } from "../state-register.js";
@@ -29,13 +28,19 @@ export const PackDiffModel = BaseModel.extend(
29
28
  modified_date: "date",
30
29
  },
31
30
 
32
- /**
33
- * @property {collections.AssetCollection} created
34
- * @property {collections.AssetCollection} deleted
35
- */
36
- collections: {
37
- created: "CreatedAssetCollection",
38
- deleted: "DeletedAssetCollection",
31
+ derived: {
32
+ created: {
33
+ fn: function () {
34
+ const url = `${this.getPlainURL()}created/`;
35
+ return new AssetCollection({ url });
36
+ },
37
+ },
38
+ deleted: {
39
+ fn: function () {
40
+ const url = `${this.getPlainURL()}deleted/`;
41
+ return new AssetCollection({ url });
42
+ },
43
+ },
39
44
  },
40
45
 
41
46
  /**