@webex/internal-plugin-avatar 3.0.0-beta.14 → 3.0.0-beta.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -3
- package/dist/avatar-url-batcher.js.map +1 -1
- package/dist/avatar-url-store.js.map +1 -1
- package/dist/avatar.js +2 -2
- package/dist/avatar.js.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +12 -12
- package/src/avatar-url-batcher.js +40 -31
- package/src/avatar-url-store.js +1 -1
- package/src/avatar.js +52 -41
- package/src/config.js +2 -2
- package/src/index.js +1 -1
- package/test/integration/spec/avatar.js +15 -14
- package/test/unit/spec/avatar-url-batcher.js +24 -15
- package/test/unit/spec/avatar-url-store.js +110 -58
- package/test/unit/spec/avatar.js +1453 -1217
package/README.md
CHANGED
|
@@ -21,14 +21,12 @@ npm install --save @webex/internal-plugin-avatar
|
|
|
21
21
|
## Usage
|
|
22
22
|
|
|
23
23
|
```js
|
|
24
|
-
|
|
25
24
|
import '@webex/internal-plugin-avatar';
|
|
26
25
|
|
|
27
26
|
import WebexCore from '@webex/webex-core';
|
|
28
27
|
|
|
29
28
|
const webex = new WebexCore();
|
|
30
|
-
webex.internal.avatar.WHATEVER
|
|
31
|
-
|
|
29
|
+
webex.internal.avatar.WHATEVER;
|
|
32
30
|
```
|
|
33
31
|
|
|
34
32
|
## Maintainers
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["AvatarUrlBatcher","Batcher","extend","namespace","handleHttpSuccess","res","all","options","body","map","req","sizes","size","response","uuid","undefined","acceptItem","handleHttpError","reason","msg","message","item","getDeferredForRequest","then","defer","reject","Error","didItemFail","logger","warn","resolve","handleItemFailure","handleItemSuccess","getDeferredForResponse","hasDefaultAvatar","defaultAvatar","url","fingerprintRequest","fingerprintResponse","prepareRequest","queue","reduce","m","o","get","set","push","payload","forEach","value","key","submitHttpRequest","webex","request","method","api","resource"],"sources":["avatar-url-batcher.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {Batcher} from '@webex/webex-core';\nimport {uniq} from 'lodash';\n\nconst AvatarUrlBatcher = Batcher.extend({\n namespace: 'Avatar',\n\n handleHttpSuccess(res) {\n // eslint-disable-next-line arrow-body-style\n return Promise.all(res.options.body.map((req) => {\n
|
|
1
|
+
{"version":3,"names":["AvatarUrlBatcher","Batcher","extend","namespace","handleHttpSuccess","res","all","options","body","map","req","sizes","size","response","uuid","undefined","acceptItem","handleHttpError","reason","msg","message","item","getDeferredForRequest","then","defer","reject","Error","didItemFail","logger","warn","resolve","handleItemFailure","handleItemSuccess","getDeferredForResponse","hasDefaultAvatar","defaultAvatar","url","fingerprintRequest","fingerprintResponse","prepareRequest","queue","reduce","m","o","get","set","push","payload","forEach","value","key","submitHttpRequest","webex","request","method","api","resource"],"sources":["avatar-url-batcher.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {Batcher} from '@webex/webex-core';\nimport {uniq} from 'lodash';\n\nconst AvatarUrlBatcher = Batcher.extend({\n namespace: 'Avatar',\n\n handleHttpSuccess(res) {\n // eslint-disable-next-line arrow-body-style\n return Promise.all(\n res.options.body.map((req) => {\n return Promise.all(\n req.sizes.map((size) => {\n const response = (res.body[req.uuid] && res.body[req.uuid][size]) || undefined;\n\n return this.acceptItem({\n response,\n uuid: req.uuid,\n size,\n });\n })\n );\n })\n );\n },\n\n handleHttpError(reason) {\n const msg = reason.message || reason.body || reason;\n\n // avoid multiple => on same line\n // eslint-disable-next-line arrow-body-style\n return Promise.all(\n reason.options.body.map((item) => {\n return Promise.all(\n item.sizes.map((size) =>\n this.getDeferredForRequest({\n uuid: item.uuid,\n size,\n })\n // I don't see a better way to do this than with an additional nesting\n // eslint-disable-next-line max-nested-callbacks\n .then((defer) => defer.reject(msg instanceof Error ? msg : new Error(msg)))\n )\n );\n })\n );\n },\n\n didItemFail(item) {\n if (item.response) {\n if (item.size !== item.response.size) {\n this.logger.warn(`Avatar: substituted size \"${item.response.size}\" for \"${item.size}\"`);\n }\n\n return Promise.resolve(false);\n }\n\n return Promise.resolve(true);\n },\n\n handleItemFailure(item) {\n return this.getDeferredForRequest(item).then((defer) => {\n defer.reject(new Error(item.response || 'Failed to retrieve avatar'));\n });\n },\n\n handleItemSuccess(item) {\n return this.getDeferredForResponse(item).then((defer) =>\n defer.resolve({\n hasDefaultAvatar: item.response.defaultAvatar,\n uuid: item.uuid,\n size: item.size,\n url: item.response.url,\n })\n );\n },\n\n fingerprintRequest(item) {\n return Promise.resolve(`${item.uuid}-${item.size}`);\n },\n\n fingerprintResponse(item) {\n return Promise.resolve(`${item.uuid}-${item.size}`);\n },\n\n prepareRequest(queue) {\n const map = queue.reduce((m, item) => {\n let o = m.get(item.uuid);\n\n if (!o) {\n o = [];\n m.set(item.uuid, o);\n }\n o.push(item.size);\n\n return m;\n }, new Map());\n\n const payload = [];\n\n map.forEach((value, key) => {\n payload.push({\n uuid: key,\n sizes: uniq(value),\n });\n });\n\n return Promise.resolve(payload);\n },\n\n submitHttpRequest(payload) {\n return this.webex.request({\n method: 'POST',\n api: 'avatar',\n resource: 'profiles/urls',\n body: payload,\n });\n },\n});\n\nexport default AvatarUrlBatcher;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["urlByUuid","AvatarUrlStore","set","item","reject","Error","uuid","size","patterns","test","ret","get","resolve","url","cacheControl","safeSetTimeout","remove","bind","sizes","forEach","one","delete"],"sources":["avatar-url-store.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\n/* eslint-disable complexity */\n\nimport {patterns} from '@webex/common';\nimport {safeSetTimeout} from '@webex/common-timers';\n\n/**\n * <uuid+size, {uuid, size, url}> map\n */\nconst urlByUuid = new WeakMap();\n\n/**\n * @class AvatarUrlStore\n */\nexport default class AvatarUrlStore {\n /**\n * @constructs {AvatarUrlStore}\n */\n constructor() {\n urlByUuid.set(this, new Map());\n }\n\n /**\n * Get the URL associated with the given uuid and size.\n *\n * @param {object} item\n * @param {string} item.uuid A user uuid\n * @param {integer}item.size the requested size\n * @returns {Promise<object>} Resolves to the avatar item {uuid, url, size, cacheControl}\n * or Rejects on bad param, not in store\n *\n * @memberOf AvatarUrlStore\n */\n get(item) {\n if (!item) {\n return Promise.reject(new Error('`item` is required'));\n }\n if (!item.uuid) {\n return Promise.reject(new Error('`item.uuid` is required'));\n }\n if (!item.size) {\n return Promise.reject(new Error('`item.size` is required'));\n }\n if (!patterns.uuid.test(item.uuid)) {\n return Promise.reject(new Error('`item.uuid` does not appear to be a uuid'));\n }\n const ret = urlByUuid.get(this).get(`${item.uuid} - ${item.size}`);\n\n if (ret) {\n return Promise.resolve(ret);\n }\n\n return Promise.reject(new Error(`No URL found by specified id: ${JSON.stringify(item)}`));\n }\n\n /**\n * Adds the given item to the store\n * @param {Object} item\n * @param {integer} item.cacheControl\n * @param {integer} item.hasDefaultAvatar\n * @param {integer} item.size\n * @param {string} item.url\n * @param {string} item.uuid\n * @returns {Promise<object>} Resolves to the added avatar item or rejects on bad params\n */\n add(item) {\n if (!item) {\n return Promise.reject(new Error('`item` is required'));\n }\n if (!item.uuid) {\n return Promise.reject(new Error('`item.uuid` is required'));\n }\n if (!item.size) {\n return Promise.reject(new Error('`item.size` is required'));\n }\n if (!patterns.uuid.test(item.uuid)) {\n return Promise.reject(new Error('`item.uuid` does not appear to be a uuid'));\n }\n if (!item.url) {\n return Promise.reject(new Error('`item.url` is required'));\n }\n if (!item.cacheControl) {\n return Promise.reject(new Error('`item.cacheControl` is required'));\n }\n\n safeSetTimeout(this.remove.bind(this, item), item.cacheControl * 1000);\n urlByUuid.get(this).set(`${item.uuid} - ${item.size}`, item);\n\n return Promise.resolve(item);\n }\n\n /**\n * Remove the URL associated with the uuid and size\n * Remove urls of all sizes if size is not given\n *\n * @param {object} item\n * @param {string} item.uuid The user unique id\n * @param {integer} item.size The size of the avatar to remove\n * @returns {Promise<true>}\n */\n remove(item) {\n const sizes = item.size && [item.size] || [40, 50, 80, 110, 135, 192, 640, 1600];\n\n sizes.forEach((one) => urlByUuid.get(this).delete(`${item.uuid} - ${one}`));\n\n return Promise.resolve(true);\n }\n}\n"],"mappings":"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
|
|
1
|
+
{"version":3,"names":["urlByUuid","AvatarUrlStore","set","item","reject","Error","uuid","size","patterns","test","ret","get","resolve","url","cacheControl","safeSetTimeout","remove","bind","sizes","forEach","one","delete"],"sources":["avatar-url-store.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\n/* eslint-disable complexity */\n\nimport {patterns} from '@webex/common';\nimport {safeSetTimeout} from '@webex/common-timers';\n\n/**\n * <uuid+size, {uuid, size, url}> map\n */\nconst urlByUuid = new WeakMap();\n\n/**\n * @class AvatarUrlStore\n */\nexport default class AvatarUrlStore {\n /**\n * @constructs {AvatarUrlStore}\n */\n constructor() {\n urlByUuid.set(this, new Map());\n }\n\n /**\n * Get the URL associated with the given uuid and size.\n *\n * @param {object} item\n * @param {string} item.uuid A user uuid\n * @param {integer}item.size the requested size\n * @returns {Promise<object>} Resolves to the avatar item {uuid, url, size, cacheControl}\n * or Rejects on bad param, not in store\n *\n * @memberOf AvatarUrlStore\n */\n get(item) {\n if (!item) {\n return Promise.reject(new Error('`item` is required'));\n }\n if (!item.uuid) {\n return Promise.reject(new Error('`item.uuid` is required'));\n }\n if (!item.size) {\n return Promise.reject(new Error('`item.size` is required'));\n }\n if (!patterns.uuid.test(item.uuid)) {\n return Promise.reject(new Error('`item.uuid` does not appear to be a uuid'));\n }\n const ret = urlByUuid.get(this).get(`${item.uuid} - ${item.size}`);\n\n if (ret) {\n return Promise.resolve(ret);\n }\n\n return Promise.reject(new Error(`No URL found by specified id: ${JSON.stringify(item)}`));\n }\n\n /**\n * Adds the given item to the store\n * @param {Object} item\n * @param {integer} item.cacheControl\n * @param {integer} item.hasDefaultAvatar\n * @param {integer} item.size\n * @param {string} item.url\n * @param {string} item.uuid\n * @returns {Promise<object>} Resolves to the added avatar item or rejects on bad params\n */\n add(item) {\n if (!item) {\n return Promise.reject(new Error('`item` is required'));\n }\n if (!item.uuid) {\n return Promise.reject(new Error('`item.uuid` is required'));\n }\n if (!item.size) {\n return Promise.reject(new Error('`item.size` is required'));\n }\n if (!patterns.uuid.test(item.uuid)) {\n return Promise.reject(new Error('`item.uuid` does not appear to be a uuid'));\n }\n if (!item.url) {\n return Promise.reject(new Error('`item.url` is required'));\n }\n if (!item.cacheControl) {\n return Promise.reject(new Error('`item.cacheControl` is required'));\n }\n\n safeSetTimeout(this.remove.bind(this, item), item.cacheControl * 1000);\n urlByUuid.get(this).set(`${item.uuid} - ${item.size}`, item);\n\n return Promise.resolve(item);\n }\n\n /**\n * Remove the URL associated with the uuid and size\n * Remove urls of all sizes if size is not given\n *\n * @param {object} item\n * @param {string} item.uuid The user unique id\n * @param {integer} item.size The size of the avatar to remove\n * @returns {Promise<true>}\n */\n remove(item) {\n const sizes = (item.size && [item.size]) || [40, 50, 80, 110, 135, 192, 640, 1600];\n\n sizes.forEach((one) => urlByUuid.get(this).delete(`${item.uuid} - ${one}`));\n\n return Promise.resolve(true);\n }\n}\n"],"mappings":"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"}
|
package/dist/avatar.js
CHANGED
|
@@ -110,7 +110,7 @@ var Avatar = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
110
110
|
var _this3 = this;
|
|
111
111
|
|
|
112
112
|
if (!user) {
|
|
113
|
-
return _promise.default.reject(new Error('
|
|
113
|
+
return _promise.default.reject(new Error("'user' is a required parameter"));
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
options = (0, _defaults2.default)(options, {
|
|
@@ -178,7 +178,7 @@ var Avatar = _webexCore.WebexPlugin.extend((_dec = (0, _common.oneFlight)({
|
|
|
178
178
|
return res.url;
|
|
179
179
|
});
|
|
180
180
|
},
|
|
181
|
-
version: "3.0.0-beta.
|
|
181
|
+
version: "3.0.0-beta.15"
|
|
182
182
|
}, ((0, _applyDecoratedDescriptor2.default)(_obj, "_fetchAllAvatarUrlSizes", [_dec], (0, _getOwnPropertyDescriptor.default)(_obj, "_fetchAllAvatarUrlSizes"), _obj), (0, _applyDecoratedDescriptor2.default)(_obj, "_fetchAvatarUrl", [_dec2], (0, _getOwnPropertyDescriptor.default)(_obj, "_fetchAvatarUrl"), _obj)), _obj)));
|
|
183
183
|
|
|
184
184
|
var _default2 = Avatar;
|
package/dist/avatar.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Avatar","WebexPlugin","extend","oneFlight","keyFactory","uuid","options","String","size","namespace","children","batcher","AvatarUrlBatcher","session","store","default","AvatarUrlStore","type","enableThumbnails","_fetchAllAvatarUrlSizes","all","config","sizes","map","request","then","item","add","cacheControl","_fetchAvatarUrl","get","catch","ignore","retrieveAvatarUrl","user","reject","Error","defaultAvatarSize","webex","internal","asUUID","hideDefaultAvatar","hasDefaultAvatar","url","setAvatar","file","detectFileType","logger","processImage","thumbnailMaxWidth","thumbnailMaxHeight","isAvatar","processedImage","upload","api","resource","device","userId","phases","$uri","finalize","method","$resource","id","res","remove"],"sources":["avatar.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {oneFlight} from '@webex/common';\nimport {detectFileType, processImage} from '@webex/helper-image';\nimport {WebexPlugin} from '@webex/webex-core';\nimport {defaults} from 'lodash';\n\nimport AvatarUrlStore from './avatar-url-store';\nimport AvatarUrlBatcher from './avatar-url-batcher';\n\nconst Avatar = WebexPlugin.extend({\n namespace: 'Avatar',\n\n children: {\n batcher: AvatarUrlBatcher
|
|
1
|
+
{"version":3,"names":["Avatar","WebexPlugin","extend","oneFlight","keyFactory","uuid","options","String","size","namespace","children","batcher","AvatarUrlBatcher","session","store","default","AvatarUrlStore","type","enableThumbnails","_fetchAllAvatarUrlSizes","all","config","sizes","map","request","then","item","add","cacheControl","_fetchAvatarUrl","get","catch","ignore","retrieveAvatarUrl","user","reject","Error","defaultAvatarSize","webex","internal","asUUID","hideDefaultAvatar","hasDefaultAvatar","url","setAvatar","file","detectFileType","logger","processImage","thumbnailMaxWidth","thumbnailMaxHeight","isAvatar","processedImage","upload","api","resource","device","userId","phases","$uri","finalize","method","$resource","id","res","remove"],"sources":["avatar.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {oneFlight} from '@webex/common';\nimport {detectFileType, processImage} from '@webex/helper-image';\nimport {WebexPlugin} from '@webex/webex-core';\nimport {defaults} from 'lodash';\n\nimport AvatarUrlStore from './avatar-url-store';\nimport AvatarUrlBatcher from './avatar-url-batcher';\n\nconst Avatar = WebexPlugin.extend({\n namespace: 'Avatar',\n\n children: {\n batcher: AvatarUrlBatcher,\n },\n\n session: {\n store: {\n default() {\n return new AvatarUrlStore();\n },\n type: 'any',\n },\n enableThumbnails: {\n default: true,\n type: 'boolean',\n },\n },\n\n @oneFlight({keyFactory: (uuid) => uuid})\n _fetchAllAvatarUrlSizes(uuid, options) {\n // fetch all possible sizes of avatar and store in cache\n return Promise.all(\n this.config.sizes.map((size) =>\n this.batcher\n .request({uuid, size})\n .then((item) => this.store.add(defaults({cacheControl: options.cacheControl}, item)))\n )\n );\n },\n\n /**\n * @private\n * Requests an avatar URL from the api\n * @param {string} uuid\n * @param {Object} options\n * @param {integer} options.size\n * @param {integer} options.cacheControl\n * @returns {Promise<string>} the avatar URL\n */\n @oneFlight({keyFactory: (uuid, options) => uuid + String(options && options.size)})\n _fetchAvatarUrl(uuid, options) {\n return this.store.get({uuid, size: options.size}).catch(() =>\n Promise.all([\n this._fetchAllAvatarUrlSizes(uuid, options),\n // just in case options.size does not fall into the predefined values above\n this.batcher.request({uuid, size: options.size}),\n ])\n // eslint-disable-next-line no-unused-vars\n .then(([ignore, item]) =>\n this.store.add(defaults({cacheControl: options.cacheControl}, item))\n )\n );\n },\n\n /**\n * Retrieves an Avatar from a cache or the api on misses.\n *\n * @param {UserObject|string} user The user, Webex user uuid, or email\n * @param {Object} [options]\n * @param {integer} [options.size] In {1600, 640, 192, 135, 110, 80, 50, 40}\n * Defaults to 80 if falsy\n * @param {boolean} [options.hideDefaultAvatar] does not return default avatar url if true. Defaults to false\n * @returns {Promise<string>} A promise that resolves to the avatar\n */\n retrieveAvatarUrl(user, options) {\n if (!user) {\n return Promise.reject(new Error(\"'user' is a required parameter\"));\n }\n\n options = defaults(options, {\n cacheControl: this.config.cacheControl,\n size: this.config.defaultAvatarSize,\n });\n\n return this.webex.internal.user\n .asUUID(user)\n .then((uuid) => this._fetchAvatarUrl(uuid, options))\n .then((item) => {\n if (options.hideDefaultAvatar) {\n return item.hasDefaultAvatar ? null : item.url;\n }\n\n return item.url;\n });\n },\n\n /**\n * Upload a new avatar for the current user\n *\n * @param {Blob|File|Buffer} file The new avatar\n * @returns {Promise} Resolves with the URL of the full-sized avatar\n */\n setAvatar(file) {\n return detectFileType(file, this.logger)\n .then((type) =>\n processImage({\n file,\n type,\n thumbnailMaxWidth: this.config.thumbnailMaxWidth,\n thumbnailMaxHeight: this.config.thumbnailMaxHeight,\n enableThumbnails: this.enableThumbnails,\n logger: this.logger,\n isAvatar: true,\n })\n )\n .then((processedImage) =>\n this.upload({\n api: 'avatar',\n resource: `profile/${this.webex.internal.device.userId}/session`,\n file: processedImage[0],\n phases: {\n upload: {\n $uri: (session) => session.url,\n },\n finalize: {\n method: 'PUT',\n api: 'avatar',\n $resource: (session) =>\n // eslint-disable-next-line max-len\n `profile/${this.webex.internal.device.userId}/session/${session.id}`,\n },\n },\n })\n )\n .then((res) => {\n // invalidate user's cached avatar\n this.store.remove({uuid: this.webex.internal.device.userId});\n\n return res.url;\n });\n },\n});\n\nexport default Avatar;\n"],"mappings":"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"}
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["avatar","batcherWait","batcherMaxCalls","batcherMaxWait","cacheControl","defaultAvatarSize","sizes","thumbnailMaxHeight","thumbnailMaxWidth"],"sources":["config.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nexport default {\n avatar: {\n batcherWait: 100,\n batcherMaxCalls: 100,\n batcherMaxWait: 1500,\n\n /**\n * @description avatar URL store TTL, allows avatar updates to eventually be propegated\n * @type {number} Number of seconds the avatar should remain in store\n */\n cacheControl: 60 * 60,\n /**\n * @description default avatar size to retrieve if no size is specified\n * @type {number}\n */\n defaultAvatarSize: 80,\n sizes: [40, 50, 80, 110, 135, 192, 640, 1600],\n /**\n * Max height for thumbnails generated when sharing an image\n * @type {number}\n */\n thumbnailMaxHeight: 960,\n /**\n * Max width for thumbnails generated when sharing an image\n * @type {number}\n */\n thumbnailMaxWidth: 640
|
|
1
|
+
{"version":3,"names":["avatar","batcherWait","batcherMaxCalls","batcherMaxWait","cacheControl","defaultAvatarSize","sizes","thumbnailMaxHeight","thumbnailMaxWidth"],"sources":["config.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nexport default {\n avatar: {\n batcherWait: 100,\n batcherMaxCalls: 100,\n batcherMaxWait: 1500,\n\n /**\n * @description avatar URL store TTL, allows avatar updates to eventually be propegated\n * @type {number} Number of seconds the avatar should remain in store\n */\n cacheControl: 60 * 60,\n /**\n * @description default avatar size to retrieve if no size is specified\n * @type {number}\n */\n defaultAvatarSize: 80,\n sizes: [40, 50, 80, 110, 135, 192, 640, 1600],\n /**\n * Max height for thumbnails generated when sharing an image\n * @type {number}\n */\n thumbnailMaxHeight: 960,\n /**\n * Max width for thumbnails generated when sharing an image\n * @type {number}\n */\n thumbnailMaxWidth: 640,\n },\n};\n"],"mappings":";;;;;;;;;;AAAA;AACA;AACA;eAEe;EACbA,MAAM,EAAE;IACNC,WAAW,EAAE,GADP;IAENC,eAAe,EAAE,GAFX;IAGNC,cAAc,EAAE,IAHV;;IAKN;AACJ;AACA;AACA;IACIC,YAAY,EAAE,KAAK,EATb;;IAUN;AACJ;AACA;AACA;IACIC,iBAAiB,EAAE,EAdb;IAeNC,KAAK,EAAE,CAAC,EAAD,EAAK,EAAL,EAAS,EAAT,EAAa,GAAb,EAAkB,GAAlB,EAAuB,GAAvB,EAA4B,GAA5B,EAAiC,IAAjC,CAfD;;IAgBN;AACJ;AACA;AACA;IACIC,kBAAkB,EAAE,GApBd;;IAqBN;AACJ;AACA;AACA;IACIC,iBAAiB,EAAE;EAzBb;AADK,C"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["registerInternalPlugin","Avatar","config"],"sources":["index.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport '@webex/internal-plugin-user';\nimport '@webex/internal-plugin-device';\n\nimport {registerInternalPlugin} from '@webex/webex-core';\n\nimport Avatar from './avatar';\nimport config from './config';\n\nregisterInternalPlugin('avatar', Avatar, {\n config
|
|
1
|
+
{"version":3,"names":["registerInternalPlugin","Avatar","config"],"sources":["index.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport '@webex/internal-plugin-user';\nimport '@webex/internal-plugin-device';\n\nimport {registerInternalPlugin} from '@webex/webex-core';\n\nimport Avatar from './avatar';\nimport config from './config';\n\nregisterInternalPlugin('avatar', Avatar, {\n config,\n});\n\nexport {default} from './avatar';\n"],"mappings":";;;;;;;;;;;;;;;;;AAIA;;AACA;;AAEA;;AAEA;;AACA;;AAVA;AACA;AACA;AAUA,IAAAA,iCAAA,EAAuB,QAAvB,EAAiCC,eAAjC,EAAyC;EACvCC,MAAM,EAANA;AADuC,CAAzC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/internal-plugin-avatar",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.15",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Joe Fuhrman <jofuhrma@cisco.com>",
|
|
@@ -21,20 +21,20 @@
|
|
|
21
21
|
]
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@webex/test-helper-chai": "3.0.0-beta.
|
|
25
|
-
"@webex/test-helper-file": "3.0.0-beta.
|
|
26
|
-
"@webex/test-helper-mock-webex": "3.0.0-beta.
|
|
27
|
-
"@webex/test-helper-test-users": "3.0.0-beta.
|
|
24
|
+
"@webex/test-helper-chai": "3.0.0-beta.15",
|
|
25
|
+
"@webex/test-helper-file": "3.0.0-beta.15",
|
|
26
|
+
"@webex/test-helper-mock-webex": "3.0.0-beta.15",
|
|
27
|
+
"@webex/test-helper-test-users": "3.0.0-beta.15",
|
|
28
28
|
"sinon": "^9.2.4"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@webex/common": "3.0.0-beta.
|
|
32
|
-
"@webex/common-timers": "3.0.0-beta.
|
|
33
|
-
"@webex/helper-image": "3.0.0-beta.
|
|
34
|
-
"@webex/internal-plugin-avatar": "3.0.0-beta.
|
|
35
|
-
"@webex/internal-plugin-device": "3.0.0-beta.
|
|
36
|
-
"@webex/internal-plugin-user": "3.0.0-beta.
|
|
37
|
-
"@webex/webex-core": "3.0.0-beta.
|
|
31
|
+
"@webex/common": "3.0.0-beta.15",
|
|
32
|
+
"@webex/common-timers": "3.0.0-beta.15",
|
|
33
|
+
"@webex/helper-image": "3.0.0-beta.15",
|
|
34
|
+
"@webex/internal-plugin-avatar": "3.0.0-beta.15",
|
|
35
|
+
"@webex/internal-plugin-device": "3.0.0-beta.15",
|
|
36
|
+
"@webex/internal-plugin-user": "3.0.0-beta.15",
|
|
37
|
+
"@webex/webex-core": "3.0.0-beta.15",
|
|
38
38
|
"lodash": "^4.17.21"
|
|
39
39
|
}
|
|
40
40
|
}
|
|
@@ -10,17 +10,21 @@ const AvatarUrlBatcher = Batcher.extend({
|
|
|
10
10
|
|
|
11
11
|
handleHttpSuccess(res) {
|
|
12
12
|
// eslint-disable-next-line arrow-body-style
|
|
13
|
-
return Promise.all(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
return Promise.all(
|
|
14
|
+
res.options.body.map((req) => {
|
|
15
|
+
return Promise.all(
|
|
16
|
+
req.sizes.map((size) => {
|
|
17
|
+
const response = (res.body[req.uuid] && res.body[req.uuid][size]) || undefined;
|
|
18
|
+
|
|
19
|
+
return this.acceptItem({
|
|
20
|
+
response,
|
|
21
|
+
uuid: req.uuid,
|
|
22
|
+
size,
|
|
23
|
+
});
|
|
24
|
+
})
|
|
25
|
+
);
|
|
26
|
+
})
|
|
27
|
+
);
|
|
24
28
|
},
|
|
25
29
|
|
|
26
30
|
handleHttpError(reason) {
|
|
@@ -28,15 +32,21 @@ const AvatarUrlBatcher = Batcher.extend({
|
|
|
28
32
|
|
|
29
33
|
// avoid multiple => on same line
|
|
30
34
|
// eslint-disable-next-line arrow-body-style
|
|
31
|
-
return Promise.all(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
return Promise.all(
|
|
36
|
+
reason.options.body.map((item) => {
|
|
37
|
+
return Promise.all(
|
|
38
|
+
item.sizes.map((size) =>
|
|
39
|
+
this.getDeferredForRequest({
|
|
40
|
+
uuid: item.uuid,
|
|
41
|
+
size,
|
|
42
|
+
})
|
|
43
|
+
// I don't see a better way to do this than with an additional nesting
|
|
44
|
+
// eslint-disable-next-line max-nested-callbacks
|
|
45
|
+
.then((defer) => defer.reject(msg instanceof Error ? msg : new Error(msg)))
|
|
46
|
+
)
|
|
47
|
+
);
|
|
35
48
|
})
|
|
36
|
-
|
|
37
|
-
// eslint-disable-next-line max-nested-callbacks
|
|
38
|
-
.then((defer) => defer.reject(msg instanceof Error ? msg : new Error(msg)))));
|
|
39
|
-
}));
|
|
49
|
+
);
|
|
40
50
|
},
|
|
41
51
|
|
|
42
52
|
didItemFail(item) {
|
|
@@ -52,20 +62,20 @@ const AvatarUrlBatcher = Batcher.extend({
|
|
|
52
62
|
},
|
|
53
63
|
|
|
54
64
|
handleItemFailure(item) {
|
|
55
|
-
return this.getDeferredForRequest(item)
|
|
56
|
-
.
|
|
57
|
-
|
|
58
|
-
});
|
|
65
|
+
return this.getDeferredForRequest(item).then((defer) => {
|
|
66
|
+
defer.reject(new Error(item.response || 'Failed to retrieve avatar'));
|
|
67
|
+
});
|
|
59
68
|
},
|
|
60
69
|
|
|
61
70
|
handleItemSuccess(item) {
|
|
62
|
-
return this.getDeferredForResponse(item)
|
|
63
|
-
|
|
71
|
+
return this.getDeferredForResponse(item).then((defer) =>
|
|
72
|
+
defer.resolve({
|
|
64
73
|
hasDefaultAvatar: item.response.defaultAvatar,
|
|
65
74
|
uuid: item.uuid,
|
|
66
75
|
size: item.size,
|
|
67
|
-
url: item.response.url
|
|
68
|
-
})
|
|
76
|
+
url: item.response.url,
|
|
77
|
+
})
|
|
78
|
+
);
|
|
69
79
|
},
|
|
70
80
|
|
|
71
81
|
fingerprintRequest(item) {
|
|
@@ -94,7 +104,7 @@ const AvatarUrlBatcher = Batcher.extend({
|
|
|
94
104
|
map.forEach((value, key) => {
|
|
95
105
|
payload.push({
|
|
96
106
|
uuid: key,
|
|
97
|
-
sizes: uniq(value)
|
|
107
|
+
sizes: uniq(value),
|
|
98
108
|
});
|
|
99
109
|
});
|
|
100
110
|
|
|
@@ -106,10 +116,9 @@ const AvatarUrlBatcher = Batcher.extend({
|
|
|
106
116
|
method: 'POST',
|
|
107
117
|
api: 'avatar',
|
|
108
118
|
resource: 'profiles/urls',
|
|
109
|
-
body: payload
|
|
119
|
+
body: payload,
|
|
110
120
|
});
|
|
111
|
-
}
|
|
112
|
-
|
|
121
|
+
},
|
|
113
122
|
});
|
|
114
123
|
|
|
115
124
|
export default AvatarUrlBatcher;
|
package/src/avatar-url-store.js
CHANGED
|
@@ -102,7 +102,7 @@ export default class AvatarUrlStore {
|
|
|
102
102
|
* @returns {Promise<true>}
|
|
103
103
|
*/
|
|
104
104
|
remove(item) {
|
|
105
|
-
const sizes = item.size && [item.size] || [40, 50, 80, 110, 135, 192, 640, 1600];
|
|
105
|
+
const sizes = (item.size && [item.size]) || [40, 50, 80, 110, 135, 192, 640, 1600];
|
|
106
106
|
|
|
107
107
|
sizes.forEach((one) => urlByUuid.get(this).delete(`${item.uuid} - ${one}`));
|
|
108
108
|
|
package/src/avatar.js
CHANGED
|
@@ -14,7 +14,7 @@ const Avatar = WebexPlugin.extend({
|
|
|
14
14
|
namespace: 'Avatar',
|
|
15
15
|
|
|
16
16
|
children: {
|
|
17
|
-
batcher: AvatarUrlBatcher
|
|
17
|
+
batcher: AvatarUrlBatcher,
|
|
18
18
|
},
|
|
19
19
|
|
|
20
20
|
session: {
|
|
@@ -22,19 +22,24 @@ const Avatar = WebexPlugin.extend({
|
|
|
22
22
|
default() {
|
|
23
23
|
return new AvatarUrlStore();
|
|
24
24
|
},
|
|
25
|
-
type: 'any'
|
|
25
|
+
type: 'any',
|
|
26
26
|
},
|
|
27
27
|
enableThumbnails: {
|
|
28
28
|
default: true,
|
|
29
|
-
type: 'boolean'
|
|
30
|
-
}
|
|
29
|
+
type: 'boolean',
|
|
30
|
+
},
|
|
31
31
|
},
|
|
32
32
|
|
|
33
33
|
@oneFlight({keyFactory: (uuid) => uuid})
|
|
34
34
|
_fetchAllAvatarUrlSizes(uuid, options) {
|
|
35
35
|
// fetch all possible sizes of avatar and store in cache
|
|
36
|
-
return Promise.all(
|
|
37
|
-
.
|
|
36
|
+
return Promise.all(
|
|
37
|
+
this.config.sizes.map((size) =>
|
|
38
|
+
this.batcher
|
|
39
|
+
.request({uuid, size})
|
|
40
|
+
.then((item) => this.store.add(defaults({cacheControl: options.cacheControl}, item)))
|
|
41
|
+
)
|
|
42
|
+
);
|
|
38
43
|
},
|
|
39
44
|
|
|
40
45
|
/**
|
|
@@ -48,14 +53,17 @@ const Avatar = WebexPlugin.extend({
|
|
|
48
53
|
*/
|
|
49
54
|
@oneFlight({keyFactory: (uuid, options) => uuid + String(options && options.size)})
|
|
50
55
|
_fetchAvatarUrl(uuid, options) {
|
|
51
|
-
return this.store.get({uuid, size: options.size})
|
|
52
|
-
|
|
56
|
+
return this.store.get({uuid, size: options.size}).catch(() =>
|
|
57
|
+
Promise.all([
|
|
53
58
|
this._fetchAllAvatarUrlSizes(uuid, options),
|
|
54
59
|
// just in case options.size does not fall into the predefined values above
|
|
55
|
-
this.batcher.request({uuid, size: options.size})
|
|
60
|
+
this.batcher.request({uuid, size: options.size}),
|
|
56
61
|
])
|
|
57
62
|
// eslint-disable-next-line no-unused-vars
|
|
58
|
-
.then(([ignore, item]) =>
|
|
63
|
+
.then(([ignore, item]) =>
|
|
64
|
+
this.store.add(defaults({cacheControl: options.cacheControl}, item))
|
|
65
|
+
)
|
|
66
|
+
);
|
|
59
67
|
},
|
|
60
68
|
|
|
61
69
|
/**
|
|
@@ -70,15 +78,16 @@ const Avatar = WebexPlugin.extend({
|
|
|
70
78
|
*/
|
|
71
79
|
retrieveAvatarUrl(user, options) {
|
|
72
80
|
if (!user) {
|
|
73
|
-
return Promise.reject(new Error('
|
|
81
|
+
return Promise.reject(new Error("'user' is a required parameter"));
|
|
74
82
|
}
|
|
75
83
|
|
|
76
84
|
options = defaults(options, {
|
|
77
85
|
cacheControl: this.config.cacheControl,
|
|
78
|
-
size: this.config.defaultAvatarSize
|
|
86
|
+
size: this.config.defaultAvatarSize,
|
|
79
87
|
});
|
|
80
88
|
|
|
81
|
-
return this.webex.internal.user
|
|
89
|
+
return this.webex.internal.user
|
|
90
|
+
.asUUID(user)
|
|
82
91
|
.then((uuid) => this._fetchAvatarUrl(uuid, options))
|
|
83
92
|
.then((item) => {
|
|
84
93
|
if (options.hideDefaultAvatar) {
|
|
@@ -97,41 +106,43 @@ const Avatar = WebexPlugin.extend({
|
|
|
97
106
|
*/
|
|
98
107
|
setAvatar(file) {
|
|
99
108
|
return detectFileType(file, this.logger)
|
|
100
|
-
.then((type) =>
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
109
|
+
.then((type) =>
|
|
110
|
+
processImage({
|
|
111
|
+
file,
|
|
112
|
+
type,
|
|
113
|
+
thumbnailMaxWidth: this.config.thumbnailMaxWidth,
|
|
114
|
+
thumbnailMaxHeight: this.config.thumbnailMaxHeight,
|
|
115
|
+
enableThumbnails: this.enableThumbnails,
|
|
116
|
+
logger: this.logger,
|
|
117
|
+
isAvatar: true,
|
|
118
|
+
})
|
|
119
|
+
)
|
|
120
|
+
.then((processedImage) =>
|
|
121
|
+
this.upload({
|
|
122
|
+
api: 'avatar',
|
|
123
|
+
resource: `profile/${this.webex.internal.device.userId}/session`,
|
|
124
|
+
file: processedImage[0],
|
|
125
|
+
phases: {
|
|
126
|
+
upload: {
|
|
127
|
+
$uri: (session) => session.url,
|
|
128
|
+
},
|
|
129
|
+
finalize: {
|
|
130
|
+
method: 'PUT',
|
|
131
|
+
api: 'avatar',
|
|
132
|
+
$resource: (session) =>
|
|
133
|
+
// eslint-disable-next-line max-len
|
|
134
|
+
`profile/${this.webex.internal.device.userId}/session/${session.id}`,
|
|
135
|
+
},
|
|
116
136
|
},
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
api: 'avatar',
|
|
120
|
-
$resource: (session) =>
|
|
121
|
-
// eslint-disable-next-line max-len
|
|
122
|
-
`profile/${this.webex.internal.device.userId}/session/${session.id}`
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}))
|
|
137
|
+
})
|
|
138
|
+
)
|
|
126
139
|
.then((res) => {
|
|
127
140
|
// invalidate user's cached avatar
|
|
128
141
|
this.store.remove({uuid: this.webex.internal.device.userId});
|
|
129
142
|
|
|
130
143
|
return res.url;
|
|
131
144
|
});
|
|
132
|
-
}
|
|
133
|
-
|
|
145
|
+
},
|
|
134
146
|
});
|
|
135
147
|
|
|
136
|
-
|
|
137
148
|
export default Avatar;
|
package/src/config.js
CHANGED
package/src/index.js
CHANGED
|
@@ -13,34 +13,35 @@ import testUsers from '@webex/test-helper-test-users';
|
|
|
13
13
|
describe('plugin-avatar', () => {
|
|
14
14
|
let mccoy, webex, spock;
|
|
15
15
|
|
|
16
|
-
before('create users', () =>
|
|
17
|
-
.then((users) => {
|
|
16
|
+
before('create users', () =>
|
|
17
|
+
testUsers.create({count: 2}).then((users) => {
|
|
18
18
|
[spock, mccoy] = users;
|
|
19
19
|
|
|
20
20
|
webex = new WebexCore({
|
|
21
21
|
credentials: {
|
|
22
|
-
authorization: spock.token
|
|
23
|
-
}
|
|
22
|
+
authorization: spock.token,
|
|
23
|
+
},
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
mccoy.webex = new WebexCore({
|
|
27
27
|
credentials: {
|
|
28
|
-
authorization: mccoy.token
|
|
29
|
-
}
|
|
28
|
+
authorization: mccoy.token,
|
|
29
|
+
},
|
|
30
30
|
});
|
|
31
|
-
})
|
|
31
|
+
})
|
|
32
|
+
);
|
|
32
33
|
|
|
33
|
-
before('register with wdm', () =>
|
|
34
|
-
webex.internal.device.register(),
|
|
35
|
-
|
|
36
|
-
]));
|
|
34
|
+
before('register with wdm', () =>
|
|
35
|
+
Promise.all([webex.internal.device.register(), mccoy.webex.internal.device.register()])
|
|
36
|
+
);
|
|
37
37
|
|
|
38
38
|
let sampleImageSmallOnePng = 'sample-image-small-one.png';
|
|
39
39
|
|
|
40
|
-
before(() =>
|
|
41
|
-
.then((file) => {
|
|
40
|
+
before(() =>
|
|
41
|
+
fh.fetch(sampleImageSmallOnePng).then((file) => {
|
|
42
42
|
sampleImageSmallOnePng = file;
|
|
43
|
-
})
|
|
43
|
+
})
|
|
44
|
+
);
|
|
44
45
|
|
|
45
46
|
// describe('#setAvatar()', () => {
|
|
46
47
|
// it('sets a user\'s avatar', () => webex.internal.avatar.setAvatar(sampleImageSmallOnePng)
|