cloudinary / cloudinary/cloudinary_npm
`context` and `metadata` Map support
- Dominant language
- JavaScript
- Stars
- 666
- Forks
- 319
- Avg merge
- 17h 18m
- Merged PRs (30d)
- 3
Description
## Bug report for Cloudinary NPM SDK
## Describe the bug in a sentence or two.
[The documentation states](https://cloudinary.com/documentation/image_upload_api_reference#upload_method) that `context` and `metadata` both support Maps when using this SDK to upload images. However, when attempting to use a Map or even a standard Object, this does not seem to be fully supported. Images are uploaded with missing or entirely omitted context and no error is thrown during the call.

## Issue Type (Can be multiple)
[ ] Build - Can’t install or import the SDK
[ ] Babel - Babel errors or cross browser issues
[ ] Performance - Performance issues
[x] Behaviour - Functions aren’t working as expected (Such as generate URL)
[x] Documentation - Inconsistency between the docs and behaviour
[ ] Incorrect Types - For typescript users who are having problems with our d.ts files
[ ] Other (Specify)
## Steps to reproduce
The issue appears to be with the `encode_context` function which is used on both `context` and `metadata` options if provided:
https://github.com/cloudinary/cloudinary_npm/blob/4e3b0f820c3ff99aad6cccd6d3874aca95d25a50/lib/utils/index.js#L566-L571
In the case of actually providing a Map, the encode function fails to encode entirely and the result is an empty string. In the case of providing an Object, the encoding fails if any of the key/value pairs are a number. When a key value pair is a number only the value is encoded and not the key which leads to unexpected results.
The best way to test is with the following:
```js
const { strict: assert } = require('assert')
const { encode_context: encode } = require('cloudinary/lib/utils')
const contextMap = new Map()
contextMap.set('storeNumber', 100148)
contextMap.set('vin', '5YJ3E1EA1JF045327')
// Fails: encoded context is an empty string
assert.equal(encode(contextMap), 'storeNumber=100148|vin=5YJ3E1EA1JF045327')
const contextObj = { storeNumber: 100148, vin: '5YJ3E1EA1JF045327' }
// Fails: encoded context is missing `storeNumber=`
assert.equal(encode(contextObj), 'storeNumber=100148|vin=5YJ3E1EA1JF045327')
```
The encoding only appears to work if an Object is supplied and all of the key/value pairs are first converted to a String.
In the meantime we've had to resort to converting our context argument to a string _before_ passing it to the Cloudinary SDK so we ensure consistency, ex:
```js
await cloudinary.uploader.upload(url, {
async: true,
context: Object.entries(context).map(val => val.join('=')).join('|')
})
```
## Versions and Libraries (fill in the version numbers)
Cloudinary_NPM SDK version - 1.26.0
Node - 14.16.1
NPM - 6.14.13
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.