monday-sdk-js 0.1.1 → 0.1.4

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 CHANGED
@@ -19,6 +19,7 @@ The SDK contains methods for server-side and client-side application development
19
19
  - [SDK capabilities](#sdk-capabilities)
20
20
  - [`monday.api`](#mondayapiquery-options--)
21
21
  - [`monday.get`](#mondaygettype-params--)
22
+ - [`monday.set`](#mondaysettype-params--)
22
23
  - [`monday.listen`](#mondaylistentypeortypes-callback-params--)
23
24
  - [`monday.execute`](#mondayexecutetype-params)
24
25
  - [`monday.oauth`](#mondayoauthoptions--)
@@ -151,6 +152,7 @@ The available types that can be requested are:
151
152
  | `'settings'` | The application settings as configured by the user that installed the app |
152
153
  | `'itemIds'` | The list of item IDs that are filtered in the current board (or all items if no filters are applied) |
153
154
  | `'sessionToken'` | A JWT token which is decoded with your app's secret and can be used as a session token between your app's frontend & backend |
155
+ | `'filter'` | The state of the _Search_ filter |
154
156
 
155
157
  **Returns:**
156
158
 
@@ -188,6 +190,46 @@ Requesting the list of items currently in view in the board:
188
190
  monday.get("itemIds").then(res => console.log(res));
189
191
  // => [234234, 4564, 234234, 67675, 576567]
190
192
  ```
193
+
194
+ <br/>
195
+
196
+ ### **`monday.set(type, params = {})`**
197
+
198
+ Used for setting up data inside your application. This method can only be used when your app is running inside an `iframe`. This can only be used in client-side apps.
199
+
200
+
201
+ **Parameters:**
202
+
203
+ - `type`: The type of data that can be set (available values below)
204
+ - `params`: Optional parameters for the action
205
+
206
+ The available types that can be set are:
207
+ | Type | Description |
208
+ |--|--|
209
+ | `'settings'` | The application settings as configured by the user that installed the app |
210
+
211
+ **Returns:**
212
+
213
+ A `Promise` that will be `resolved` to the set method response.
214
+
215
+ **Examples:**
216
+
217
+ Setting application settings data:
218
+ ```js
219
+ monday.set("settings").then(res => ...);
220
+ ```
221
+
222
+ Example application settings object that we are able to set for a board view:
223
+ ```js
224
+ // Board view settings example
225
+ {
226
+ "text": "textual value",
227
+ "color": "#037f4c",
228
+ "date": "2022-08-25"
229
+ "checkbox1": false
230
+ "textarea": "line1\nline2\n.....\nline n"
231
+ }
232
+ ```
191
233
  <br/>
192
234
 
193
235
  ### **`monday.listen(typeOrTypes, callback, params = {})`**
@@ -207,6 +249,7 @@ You can subscribe to the following types of events:
207
249
  | `'settings'` | Fired when a setting value is changed by the user |
208
250
  | `'itemIds'` | Fired when the board filter changes, which impacts the list of items currently in view |
209
251
  | `'events'` | Fired when an interaction takes place with the board/dashboard |
252
+ | `'filter'` | Fired when the _Search_ filter changes |
210
253
 
211
254
  **Returns:**
212
255
 
@@ -249,7 +292,7 @@ A `Promise` that will optionally be resolved to the return value from the actio
249
292
  **Action types:**
250
293
 
251
294
  #### Open item card
252
- Opens a popup card with information from the selected item
295
+ Opens a modal with information from the selected item
253
296
 
254
297
  **type**
255
298
  `'openItemCard'`
@@ -316,6 +359,154 @@ monday.execute("notice", {
316
359
  });
317
360
  ```
318
361
 
362
+ #### Open files preview dialog
363
+ Opens a modal with the preview of an asset
364
+
365
+ **type**
366
+ `'openFilesDialog'`
367
+
368
+ **params**
369
+
370
+ | Parameter|Type | Description | Required | Default Value |
371
+ | --- | --- | --- | --- | --- |
372
+ | boardId| Integer | The ID of the board | Yes | |
373
+ | itemId| Integer | The ID of the item, which contains an asset | Yes | |
374
+ | columnId| String | The ID of the column, which contains an asset | Yes | |
375
+ | assetId| Integer | The ID of the asset to open | Yes | |
376
+
377
+ **Example**
378
+ ```javascript
379
+ monday.execute('openFilesDialog', {
380
+ boardId: 12345,
381
+ itemId: 23456,
382
+ columnId: 'files',
383
+ assetId: 34567
384
+ })
385
+ ```
386
+
387
+ #### Trigger file upload process
388
+ Opens a modal to let the current user upload a file to a specific file column.
389
+
390
+ Returns a promise. In case of error, the promise is rejected
391
+
392
+ After the file is successfully uploaded, the "change_column_value" event will be triggered.
393
+ See the [`monday.listen`](#mondaylistentypeortypes-callback-params--)('events', callback) method to subscribe to these events.
394
+
395
+ *Requires boards:write scope*
396
+
397
+ **type**
398
+ `'triggerFilesUpload'`
399
+
400
+ **params**
401
+
402
+ | Parameter|Type | Description | Required | Default Value |
403
+ | --- | --- | --- | --- | --- |
404
+ | boardId| Integer | The ID of the board | Yes | |
405
+ | itemId| Integer | The ID of the item, which contains an asset | Yes | |
406
+ | columnId| String | The ID of the file column, where file should be uploaded | Yes | |
407
+
408
+ **Example**
409
+ ```javascript
410
+ monday.execute('triggerFilesUpload', {
411
+ boardId: 12345,
412
+ itemId: 23456,
413
+ columnId: 'files'
414
+ })
415
+ ```
416
+
417
+ #### Open modal
418
+ Opens a new modal window as an iFrame.
419
+
420
+ **type**
421
+ `'openAppFeatureModal'`
422
+
423
+ **params**
424
+
425
+ | Parameter|Type | Description | Required | Default Value |
426
+ | --- | --- | --- | --- | --- |
427
+ | url | String | The URL of the page displayed in the modal | No | current iFrame's URL |
428
+ | urlPath | String | Subdirectory or path of the URL to open | No | |
429
+ | urlParams | Object | Query parameters for the URL | No | |
430
+ | width | String | The width of the modal | No | "0px" |
431
+ | height | String | The height of the modal | No | "0px" |
432
+
433
+ **Example**
434
+ ```javascript
435
+ monday.execute('openAppFeatureModal', { urlPath, urlParams, height, width }).then((res) => {
436
+ console.log(res.data);
437
+ {"close": true}
438
+ // The above is a callback to see if a user closed the modal from the inside. This is useful should you want to run some logic within the app window.
439
+ });
440
+ ```
441
+
442
+ Note: make sure the urlPath you pass is a relative URL and not an absolute URL.
443
+
444
+ #### Close modal
445
+ Closes the modal window.
446
+
447
+ **type**
448
+ `'closeAppFeatureModal'`
449
+
450
+ **params**
451
+ This method does not have any parameters.
452
+
453
+ **Example**
454
+ ```javascript
455
+ monday.execute('closeAppFeatureModal').then((res) => {
456
+ console.log(res.data);
457
+ });
458
+ ```
459
+
460
+ #### Value created for user
461
+ Notifies the monday platform that user gains a first value in an app.
462
+
463
+ **type**
464
+ `'value'`
465
+
466
+ **params**
467
+ This method does not have any parameters.
468
+
469
+ **Example**
470
+ ```javascript
471
+ monday.execute('valueCreatedForUser').then((res) => {
472
+ console.log(res.data);
473
+ });
474
+ ```
475
+
476
+ #### Open setting window
477
+ Opens view settings window
478
+
479
+ **type**
480
+ `'value'`
481
+
482
+ **params**
483
+ This method does not have any parameters.
484
+
485
+ **Example**
486
+ ```javascript
487
+ monday.execute('openSettings').then((res) => {
488
+ console.log(res.data);
489
+ // note that method will open view settings, unless settings were alreday opened
490
+ });
491
+ ```
492
+
493
+ #### Close setting window
494
+ Closes view settings window
495
+
496
+ **type**
497
+ `'value'`
498
+
499
+ **params**
500
+ This method does not have any parameters.
501
+
502
+ **Example**
503
+ ```javascript
504
+ monday.execute('closeSettings').then((res) => {
505
+ console.log(res.data);
506
+ // note that method will close view settings, unless settings were alreday closed
507
+ });
508
+ ```
509
+
319
510
  ### **`monday.oauth(options = {})`**
320
511
  Performs a client-side redirection of the user to the monday OAuth screen with your client ID embedded in the URL, in order to get their approval to generate a temporary OAuth token based on your requested permission scopes.
321
512
 
@@ -383,7 +574,7 @@ Store a value in the database:
383
574
  ```js
384
575
  monday.storage.instance.setItem('mykey', 'Lorem Ipsum').then(res => {
385
576
  console.log(res);
386
- }
577
+ });
387
578
  // => { "success": true }
388
579
  ```
389
580
 
@@ -391,7 +582,7 @@ Retrieve a previously stored value in the database:
391
582
  ```js
392
583
  monday.storage.instance.getItem('mykey').then(res => {
393
584
  console.log(res.data.value);
394
- }
585
+ });
395
586
  // => 'Lorem Ipsum'
396
587
  ```
397
588
 
package/dist/main.js CHANGED
@@ -1 +1 @@
1
- !function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=3)}([function(e,t){const n="undefined"!=typeof window&&void 0!==window.document;e.exports={convertToArrayIfNeeded:e=>Array.isArray(e)?e:[e],isBrowser:n}},function(e,t,n){e.exports=n(5)},function(e,t,n){(function(t){const{isBrowser:r}=n(0),i=!r&&!1,o=i&&t.env.MONDAY_COM_PROTOCOL||"https",s=i&&t.env.MONDAY_COM_DOMAIN||"monday.com",a=`${o}://api.${s}/v2`,c=`${o}://auth.${s}/oauth2/authorize`,u=`${o}://auth.${s}/oauth2/token`;e.exports={MONDAY_DOMAIN:s,MONDAY_PROTOCOL:o,MONDAY_API_URL:a,MONDAY_OAUTH_URL:c,MONDAY_OAUTH_TOKEN_URL:u}}).call(this,n(6))},function(e,t,n){var r,i;const{isBrowser:o}=n(0),s=n(o?4:12);"undefined"!=typeof self&&self,void 0===(i="function"==typeof(r=function(){return window.mondaySdk=s,s})?r.call(t,n,t,e):r)||(e.exports=i)},function(e,t,n){const r=n(1),{MONDAY_OAUTH_URL:i}=n(2),{convertToArrayIfNeeded:o}=n(0),{initScrollHelperIfNeeded:s}=n(9),{initBackgroundTracking:a}=n(10),c=[];class u{constructor(e={}){this._clientId=e.clientId,this._apiToken=e.apiToken,this.listeners={},this.setClientId=this.setClientId.bind(this),this.setToken=this.setToken.bind(this),this.api=this.api.bind(this),this.listen=this.listen.bind(this),this.get=this.get.bind(this),this.execute=this.execute.bind(this),this.oauth=this.oauth.bind(this),this._receiveMessage=this._receiveMessage.bind(this),this.storage={instance:{setItem:this.setStorageInstanceItem.bind(this),getItem:this.getStorageInstanceItem.bind(this),deleteItem:this.deleteStorageInstanceItem.bind(this)}},window.addEventListener("message",this._receiveMessage,!1),e.withoutScrollHelper||s(),a(this)}setClientId(e){this._clientId=e}setToken(e){this._apiToken=e}api(e,t={}){const n={query:e,variables:t.variables},i=t.token||this._apiToken;return i?r.execute(n,i):new Promise((e,t)=>{this._localApi("api",{params:n}).then(t=>{e(t.data)}).catch(e=>t(e))})}listen(e,t,n){o(e).forEach(e=>{this._addListener(e,t),this._localApi("listen",{type:e,params:n})})}get(e,t){return this._localApi("get",{type:e,params:t})}execute(e,t){return this._localApi("execute",{type:e,params:t})}track(e,t){return this.execute("track",{name:e,data:t})}oauth(e={}){const t=e.clientId||this._clientId;if(!t)throw new Error("clientId is required");const n=`${e.mondayOauthUrl||i}?client_id=${t}`;window.location=n}setStorageInstanceItem(e,t,n={}){return this._localApi("storage",{method:"set",key:e,value:t,options:n,segment:"instance"})}getStorageInstanceItem(e,t={}){return this._localApi("storage",{method:"get",key:e,options:t,segment:"instance"})}deleteStorageInstanceItem(e,t={}){return this._localApi("storage",{method:"delete",key:e,options:t,segment:"instance"})}_localApi(e,t){return new Promise((r,i)=>{const o=this._generateRequestId(),s=this._clientId,a=n(11).version;window.parent.postMessage({method:e,args:t,requestId:o,clientId:s,version:a},"*"),this._addListener(o,e=>{e.errorMessage?i(new Error(e.errorMessage)):r(e)})})}_receiveMessage(e){const{method:t,type:n,requestId:r}=e.data;let i=[...this.listeners[t]||c,...this.listeners[n]||c,...this.listeners[r]||c];i&&i.forEach(t=>{try{t(e.data)}catch(e){console.error("Message callback error: ",e)}})}_addListener(e,t){this.listeners[e]=this.listeners[e]||[],this.listeners[e].push(t)}_generateRequestId(){return Math.random().toString(36).substr(2,9)}_removeEventListener(){window.removeEventListener("message",this._receiveMessage,!1)}_clearListeners(){this.listeners=[]}}e.exports=function(e={}){return new u(e)}},function(e,t,n){const{MONDAY_API_URL:r,MONDAY_OAUTH_TOKEN_URL:i}=n(2),o=n(7);e.exports={execute:async function(e,t,n={}){if(!t&&n.url!==i)throw new Error("Token is required");const s=`${n.url||r}${n.path||""}`;let a=await function(e,t,n,r={}){return o.nodeFetch(e,{method:r.method||"POST",body:JSON.stringify(t||{}),headers:{Authorization:n,"Content-Type":"application/json"}})}(s,e,t,n);try{return await a.json()}catch(e){throw new Error("Could not parse JSON from monday.com's GraphQL API response")}},COULD_NOT_PARSE_JSON_RESPONSE_ERROR:"Could not parse JSON from monday.com's GraphQL API response"}},function(e,t){var n,r,i=e.exports={};function o(){throw new Error("setTimeout has not been defined")}function s(){throw new Error("clearTimeout has not been defined")}function a(e){if(n===setTimeout)return setTimeout(e,0);if((n===o||!n)&&setTimeout)return n=setTimeout,setTimeout(e,0);try{return n(e,0)}catch(t){try{return n.call(null,e,0)}catch(t){return n.call(this,e,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:o}catch(e){n=o}try{r="function"==typeof clearTimeout?clearTimeout:s}catch(e){r=s}}();var c,u=[],l=!1,d=-1;function h(){l&&c&&(l=!1,c.length?u=c.concat(u):d=-1,u.length&&p())}function p(){if(!l){var e=a(h);l=!0;for(var t=u.length;t;){for(c=u,u=[];++d<t;)c&&c[d].run();d=-1,t=u.length}c=null,l=!1,function(e){if(r===clearTimeout)return clearTimeout(e);if((r===s||!r)&&clearTimeout)return r=clearTimeout,clearTimeout(e);try{r(e)}catch(t){try{return r.call(null,e)}catch(t){return r.call(this,e)}}}(e)}}function f(e,t){this.fun=e,this.array=t}function m(){}i.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];u.push(new f(e,t)),1!==u.length||l||a(p)},f.prototype.run=function(){this.fun.apply(null,this.array)},i.title="browser",i.browser=!0,i.env={},i.argv=[],i.version="",i.versions={},i.on=m,i.addListener=m,i.once=m,i.off=m,i.removeListener=m,i.removeAllListeners=m,i.emit=m,i.prependListener=m,i.prependOnceListener=m,i.listeners=function(e){return[]},i.binding=function(e){throw new Error("process.binding is not supported")},i.cwd=function(){return"/"},i.chdir=function(e){throw new Error("process.chdir is not supported")},i.umask=function(){return 0}},function(e,t,n){const r=n(8);e.exports={nodeFetch:function(e,t={}){return r(e,t)}}},function(e,t,n){"use strict";var r=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if(void 0!==r)return r;throw new Error("unable to locate global object")}();e.exports=t=r.fetch,t.default=r.fetch.bind(r),t.Headers=r.Headers,t.Request=r.Request,t.Response=r.Response},function(e,t){let n=!1;e.exports={initScrollHelperIfNeeded:function(){if(n)return;n=!0;const e=document.createElement("style");e.appendChild(document.createTextNode('body::before { content: ""; position: fixed; top: 0; right: 0; bottom: 0; left: 0; pointer-events: none; z-index: 2147483647; /* mondaySdk css - can be disabled with: mondaySdk({withoutScrollHelper: true }) */ }')),(document.head||document.getElementsByTagName("head")[0]).appendChild(e)}}},function(e,t){let n=!1;e.exports={initBackgroundTracking:e=>{if(n)return;n=!0;const t=()=>{e.track("ping")};t(),setInterval(t,3e5)}}},function(e){e.exports=JSON.parse('{"name":"monday-sdk-js","version":"0.1.0","private":false,"repository":"https://github.com/mondaycom/monday-sdk-js","main":"src/index.js","author":"talharamati <tal@monday.com>","license":"MIT","files":["LICENSE","README.md","dist/","src/","server-sdk.js"],"dependencies":{"@types/source-map":"^0.5.2","node-fetch":"^2.6.0"},"devDependencies":{"@babel/cli":"^7.6.0","@babel/core":"^7.6.0","@babel/node":"^7.6.1","@babel/preset-env":"^7.6.0","@babel/preset-react":"^7.0.0","@babel/register":"^7.6.0","babel-loader":"^8.0.6","chai":"^4.2.0","eslint":"^6.8.0","jsdom":"^16.2.0","mocha":"^7.1.0","prettier":"^1.19.1","sinon":"^9.0.0","sinon-chai":"^3.5.0","webpack":"^4.38.0","webpack-cli":"^3.3.6","webpack-dev-server":"^3.7.2"},"scripts":{"start":"webpack-dev-server","build":"webpack --mode=production --env.WEBPACK_BUILD=true","test":"mocha \'./src/**/*-test.js\'","test:watch":"mocha \'./src/**/*-test.js\' --watch","precommit":"yarn lint && yarn style-check","lint":"eslint \'./src/**/*.*\'","style-check":"prettier --check \'./src/**/*.js\'"}}')},function(e,t,n){const r=n(1),{oauthToken:i}=n(13);class o{constructor(e={}){this._token=e.token,this.setToken=this.setToken.bind(this),this.api=this.api.bind(this)}setToken(e){this._token=e}async api(e,t={}){const n={query:e,variables:t.variables},i=t.token||this._token;if(!i)throw new Error("Should send 'token' as an option or call mondaySdk.setToken(TOKEN)");return await r.execute(n,i)}oauthToken(e,t,n){return i(e,t,n)}}e.exports=function(e={}){return new o(e)}},function(e,t,n){const{execute:r}=n(1),{MONDAY_OAUTH_TOKEN_URL:i}=n(2);e.exports={oauthToken:(e,t,n)=>r({code:e,client_id:t,client_secret:n},null,{url:i})}}]);
1
+ !function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=3)}([function(e,t){const n="undefined"!=typeof window&&void 0!==window.document;e.exports={convertToArrayIfNeeded:e=>Array.isArray(e)?e:[e],isBrowser:n}},function(e,t,n){e.exports=n(5)},function(e,t,n){(function(t){const{isBrowser:r}=n(0),i=!r&&!1,o=i&&t.env.MONDAY_COM_PROTOCOL||"https",s=i&&t.env.MONDAY_COM_DOMAIN||"monday.com",a=`${o}://api.${s}/v2`,c=`${o}://auth.${s}/oauth2/authorize`,u=`${o}://auth.${s}/oauth2/token`;e.exports={MONDAY_DOMAIN:s,MONDAY_PROTOCOL:o,MONDAY_API_URL:a,MONDAY_OAUTH_URL:c,MONDAY_OAUTH_TOKEN_URL:u}}).call(this,n(6))},function(e,t,n){var r,i;const{isBrowser:o}=n(0),s=n(o?4:12);"undefined"!=typeof self&&self,void 0===(i="function"==typeof(r=function(){return window.mondaySdk=s,s})?r.call(t,n,t,e):r)||(e.exports=i)},function(e,t,n){const r=n(1),{MONDAY_OAUTH_URL:i}=n(2),{convertToArrayIfNeeded:o}=n(0),{initScrollHelperIfNeeded:s}=n(9),{initBackgroundTracking:a}=n(10),c=[];class u{constructor(e={}){this._clientId=e.clientId,this._apiToken=e.apiToken,this.listeners={},this.setClientId=this.setClientId.bind(this),this.setToken=this.setToken.bind(this),this.api=this.api.bind(this),this.listen=this.listen.bind(this),this.get=this.get.bind(this),this.set=this.set.bind(this),this.execute=this.execute.bind(this),this.oauth=this.oauth.bind(this),this._receiveMessage=this._receiveMessage.bind(this),this.storage={instance:{setItem:this.setStorageInstanceItem.bind(this),getItem:this.getStorageInstanceItem.bind(this),deleteItem:this.deleteStorageInstanceItem.bind(this)}},window.addEventListener("message",this._receiveMessage,!1),e.withoutScrollHelper||s(),a(this)}setClientId(e){this._clientId=e}setToken(e){this._apiToken=e}api(e,t={}){const n={query:e,variables:t.variables},i=t.token||this._apiToken;return i?r.execute(n,i):new Promise((e,t)=>{this._localApi("api",{params:n}).then(t=>{e(t.data)}).catch(e=>t(e))})}listen(e,t,n){o(e).forEach(e=>{this._addListener(e,t),this._localApi("listen",{type:e,params:n})})}get(e,t){return this._localApi("get",{type:e,params:t})}set(e,t){return this._localApi("set",{type:e,params:t})}execute(e,t){return this._localApi("execute",{type:e,params:t})}track(e,t){return this.execute("track",{name:e,data:t})}oauth(e={}){const t=e.clientId||this._clientId;if(!t)throw new Error("clientId is required");const n=`${e.mondayOauthUrl||i}?client_id=${t}`;window.location=n}setStorageInstanceItem(e,t,n={}){return this._localApi("storage",{method:"set",key:e,value:t,options:n,segment:"instance"})}getStorageInstanceItem(e,t={}){return this._localApi("storage",{method:"get",key:e,options:t,segment:"instance"})}deleteStorageInstanceItem(e,t={}){return this._localApi("storage",{method:"delete",key:e,options:t,segment:"instance"})}_localApi(e,t){return new Promise((r,i)=>{const o=this._generateRequestId(),s=this._clientId,a=n(11).version;window.parent.postMessage({method:e,args:t,requestId:o,clientId:s,version:a},"*"),this._addListener(o,e=>{if(e.errorMessage){const t=new Error(e.errorMessage);t.data=e.data,i(t)}else r(e)})})}_receiveMessage(e){const{method:t,type:n,requestId:r}=e.data;let i=[...this.listeners[t]||c,...this.listeners[n]||c,...this.listeners[r]||c];i&&i.forEach(t=>{try{t(e.data)}catch(e){console.error("Message callback error: ",e)}})}_addListener(e,t){this.listeners[e]=this.listeners[e]||[],this.listeners[e].push(t)}_generateRequestId(){return Math.random().toString(36).substr(2,9)}_removeEventListener(){window.removeEventListener("message",this._receiveMessage,!1)}_clearListeners(){this.listeners=[]}}e.exports=function(e={}){return new u(e)}},function(e,t,n){const{MONDAY_API_URL:r,MONDAY_OAUTH_TOKEN_URL:i}=n(2),o=n(7),s="Could not parse JSON from monday.com's GraphQL API response",a="Token is required",c="Received timeout from monday.com's GraphQL API";e.exports={execute:async function(e,t,n={}){if(!t&&n.url!==i)throw new Error(a);const u=`${n.url||r}${n.path||""}`;let l=await function(e,t,n,r={}){return o.nodeFetch(e,{method:r.method||"POST",body:JSON.stringify(t||{}),headers:{Authorization:n,"Content-Type":"application/json"}})}(u,e,t,n);const d=l.status,h=l.headers.get("content-type");if(!h||!h.includes("application/json")){if(504===d)throw new Error(c);const e=await l.text();throw new Error(e)}try{return await l.json()}catch(e){throw new Error(s)}},COULD_NOT_PARSE_JSON_RESPONSE_ERROR:s,TOKEN_IS_REQUIRED_ERROR:a,API_TIMEOUT_ERROR:c}},function(e,t){var n,r,i=e.exports={};function o(){throw new Error("setTimeout has not been defined")}function s(){throw new Error("clearTimeout has not been defined")}function a(e){if(n===setTimeout)return setTimeout(e,0);if((n===o||!n)&&setTimeout)return n=setTimeout,setTimeout(e,0);try{return n(e,0)}catch(t){try{return n.call(null,e,0)}catch(t){return n.call(this,e,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:o}catch(e){n=o}try{r="function"==typeof clearTimeout?clearTimeout:s}catch(e){r=s}}();var c,u=[],l=!1,d=-1;function h(){l&&c&&(l=!1,c.length?u=c.concat(u):d=-1,u.length&&p())}function p(){if(!l){var e=a(h);l=!0;for(var t=u.length;t;){for(c=u,u=[];++d<t;)c&&c[d].run();d=-1,t=u.length}c=null,l=!1,function(e){if(r===clearTimeout)return clearTimeout(e);if((r===s||!r)&&clearTimeout)return r=clearTimeout,clearTimeout(e);try{r(e)}catch(t){try{return r.call(null,e)}catch(t){return r.call(this,e)}}}(e)}}function f(e,t){this.fun=e,this.array=t}function m(){}i.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];u.push(new f(e,t)),1!==u.length||l||a(p)},f.prototype.run=function(){this.fun.apply(null,this.array)},i.title="browser",i.browser=!0,i.env={},i.argv=[],i.version="",i.versions={},i.on=m,i.addListener=m,i.once=m,i.off=m,i.removeListener=m,i.removeAllListeners=m,i.emit=m,i.prependListener=m,i.prependOnceListener=m,i.listeners=function(e){return[]},i.binding=function(e){throw new Error("process.binding is not supported")},i.cwd=function(){return"/"},i.chdir=function(e){throw new Error("process.chdir is not supported")},i.umask=function(){return 0}},function(e,t,n){const r=n(8);e.exports={nodeFetch:function(e,t={}){return r(e,t)}}},function(e,t,n){"use strict";var r=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if(void 0!==r)return r;throw new Error("unable to locate global object")}();e.exports=t=r.fetch,t.default=r.fetch.bind(r),t.Headers=r.Headers,t.Request=r.Request,t.Response=r.Response},function(e,t){let n=!1;e.exports={initScrollHelperIfNeeded:function(){if(n)return;n=!0;const e=document.createElement("style");e.appendChild(document.createTextNode('body::before { content: ""; position: fixed; top: 0; right: 0; bottom: 0; left: 0; pointer-events: none; z-index: 2147483647; /* mondaySdk css - can be disabled with: mondaySdk({withoutScrollHelper: true }) */ }')),(document.head||document.getElementsByTagName("head")[0]).appendChild(e)}}},function(e,t){let n=!1;e.exports={initBackgroundTracking:e=>{if(n)return;n=!0;const t=()=>{e.track("ping")};t(),setInterval(t,3e5)}}},function(e){e.exports=JSON.parse('{"name":"monday-sdk-js","version":"0.1.3","private":false,"repository":"https://github.com/mondaycom/monday-sdk-js","main":"src/index.js","author":"talharamati <tal@monday.com>","license":"MIT","files":["LICENSE","README.md","dist/","src/","server-sdk.js"],"dependencies":{"@types/source-map":"^0.5.2","node-fetch":"^2.6.0"},"devDependencies":{"@babel/cli":"^7.6.0","@babel/core":"^7.6.0","@babel/node":"^7.6.1","@babel/preset-env":"^7.6.0","@babel/preset-react":"^7.0.0","@babel/register":"^7.6.0","babel-loader":"^8.0.6","chai":"^4.2.0","eslint":"^6.8.0","jsdom":"^16.2.0","mocha":"^7.1.0","prettier":"^1.19.1","sinon":"^9.0.0","sinon-chai":"^3.5.0","webpack":"^4.38.0","webpack-cli":"^3.3.6","webpack-dev-server":"^3.7.2"},"scripts":{"start":"webpack-dev-server","build":"webpack --mode=production --env.WEBPACK_BUILD=true","test":"mocha \'./src/**/*-test.js\'","test:watch":"mocha \'./src/**/*-test.js\' --watch","precommit":"yarn lint && yarn style-check","lint":"eslint \'./src/**/*.*\'","style-check":"prettier --check \'./src/**/*.js\'"}}')},function(e,t,n){const r=n(1),{oauthToken:i}=n(13),o="Should send 'token' as an option or call mondaySdk.setToken(TOKEN)";class s{constructor(e={}){this._token=e.token,this.setToken=this.setToken.bind(this),this.api=this.api.bind(this)}setToken(e){this._token=e}async api(e,t={}){const n={query:e,variables:t.variables},i=t.token||this._token;if(!i)throw new Error(o);return await r.execute(n,i)}oauthToken(e,t,n){return i(e,t,n)}}e.exports=function(e={}){return new s(e)}},function(e,t,n){const{execute:r}=n(1),{MONDAY_OAUTH_TOKEN_URL:i}=n(2);e.exports={oauthToken:(e,t,n)=>{return r({code:e,client_id:t,client_secret:n},null,{url:i})}}}]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "monday-sdk-js",
3
- "version": "0.1.1",
3
+ "version": "0.1.4",
4
4
  "private": false,
5
5
  "repository": "https://github.com/mondaycom/monday-sdk-js",
6
6
  "main": "src/index.js",
@@ -170,10 +170,11 @@ describe("Monday Client Test API - Returning data", () => {
170
170
  it("API should reject the promise, when host raises an event with errorMessage", done => {
171
171
  const clientId = "clientId";
172
172
  const errorMessage = "My custom error";
173
+ const errorData = { errors: ["1", "2", "3"] };
173
174
  function onPostMessage(event) {
174
175
  const { requestId, method, type } = event.data;
175
176
  if (method === "api" && !event.data.errorMessage) {
176
- window.postMessage({ requestId, data: null, method, type, errorMessage: errorMessage }, "*");
177
+ window.postMessage({ requestId, data: errorData, method, type, errorMessage: errorMessage }, "*");
177
178
  //because in tests we don't have 2 different window object (parent and iframe) they are exchanging in the same
178
179
  //events space, so here we need to stop the initial SDK event propogation to not allow SDK to react to it's own event
179
180
  event.stopImmediatePropagation();
@@ -185,6 +186,7 @@ describe("Monday Client Test API - Returning data", () => {
185
186
  mondayClient.api("query").catch(err => {
186
187
  expect(err).to.be.ok;
187
188
  expect(err.message).to.be.equal(errorMessage);
189
+ expect(err.data).to.be.equal(errorData);
188
190
  done();
189
191
  });
190
192
  clock.tick(5);
package/src/client.js CHANGED
@@ -18,6 +18,7 @@ class MondayClientSdk {
18
18
  this.api = this.api.bind(this);
19
19
  this.listen = this.listen.bind(this);
20
20
  this.get = this.get.bind(this);
21
+ this.set = this.set.bind(this);
21
22
  this.execute = this.execute.bind(this);
22
23
  this.oauth = this.oauth.bind(this);
23
24
  this._receiveMessage = this._receiveMessage.bind(this);
@@ -74,6 +75,10 @@ class MondayClientSdk {
74
75
  return this._localApi("get", { type, params });
75
76
  }
76
77
 
78
+ set(type, params) {
79
+ return this._localApi("set", { type, params });
80
+ }
81
+
77
82
  execute(type, params) {
78
83
  return this._localApi("execute", { type, params });
79
84
  }
@@ -114,7 +119,9 @@ class MondayClientSdk {
114
119
  window.parent.postMessage({ method, args, requestId, clientId, version }, "*");
115
120
  this._addListener(requestId, data => {
116
121
  if (data.errorMessage) {
117
- reject(new Error(data.errorMessage));
122
+ const error = new Error(data.errorMessage);
123
+ error.data = data.data;
124
+ reject(error);
118
125
  } else {
119
126
  resolve(data);
120
127
  }
@@ -10,7 +10,9 @@ describe("mondayApiClient", () => {
10
10
  fetchMock = sinon.stub(async () => {
11
11
  return { data: "some_data" };
12
12
  });
13
- nodeFetchStub = sinon.stub(fetch, "nodeFetch").resolves({ json: fetchMock });
13
+ nodeFetchStub = sinon
14
+ .stub(fetch, "nodeFetch")
15
+ .resolves({ json: fetchMock, headers: { get: () => "application/json" } });
14
16
  });
15
17
 
16
18
  afterEach(() => {
@@ -32,18 +34,18 @@ describe("mondayApiClient", () => {
32
34
  });
33
35
  });
34
36
 
35
- it("should throw error if token is missing", async () => {
37
+ it(`should throw ${mondayApiClient.TOKEN_IS_REQUIRED_ERROR}`, async () => {
36
38
  let errorMessage;
37
39
  try {
38
40
  await mondayApiClient.execute("query { boards { id, name }}");
39
41
  } catch (err) {
40
42
  errorMessage = err.message;
41
43
  }
42
- expect(errorMessage).to.eq("Token is required");
44
+ expect(errorMessage).to.eq(mondayApiClient.TOKEN_IS_REQUIRED_ERROR);
43
45
  });
44
46
 
45
- it(`sould throw ${mondayApiClient.COULD_NOT_PARSE_JSON_RESPONSE_ERROR}`, async () => {
46
- nodeFetchStub.returns({ json: "not json" });
47
+ it(`should throw ${mondayApiClient.COULD_NOT_PARSE_JSON_RESPONSE_ERROR}`, async () => {
48
+ nodeFetchStub.returns({ json: "not json", headers: { get: () => "application/json" } });
47
49
  let errorMessage;
48
50
  try {
49
51
  await mondayApiClient.execute("query { boards { id, name }}", "api_token");
@@ -52,4 +54,15 @@ describe("mondayApiClient", () => {
52
54
  }
53
55
  expect(errorMessage).to.eq(mondayApiClient.COULD_NOT_PARSE_JSON_RESPONSE_ERROR);
54
56
  });
57
+
58
+ it(`should throw ${mondayApiClient.API_TIMEOUT_ERROR}`, async () => {
59
+ nodeFetchStub.returns({ headers: { get: () => "text/plain" }, status: 504 });
60
+ let errorMessage;
61
+ try {
62
+ await mondayApiClient.execute("query { boards { id, name }}", "api_token");
63
+ } catch (err) {
64
+ errorMessage = err.message;
65
+ }
66
+ expect(errorMessage).to.eq(mondayApiClient.API_TIMEOUT_ERROR);
67
+ });
55
68
  });
@@ -3,6 +3,7 @@ const fetch = require("./fetch");
3
3
 
4
4
  const COULD_NOT_PARSE_JSON_RESPONSE_ERROR = "Could not parse JSON from monday.com's GraphQL API response";
5
5
  const TOKEN_IS_REQUIRED_ERROR = "Token is required";
6
+ const API_TIMEOUT_ERROR = "Received timeout from monday.com's GraphQL API";
6
7
 
7
8
  function apiRequest(url, data, token, options = {}) {
8
9
  return fetch.nodeFetch(url, {
@@ -23,6 +24,17 @@ async function execute(data, token, options = {}) {
23
24
  const fullUrl = `${url}${path}`;
24
25
  let response = await apiRequest(fullUrl, data, token, options);
25
26
 
27
+ const responseStatusCode = response.status;
28
+ const responseContentType = response.headers.get("content-type");
29
+ if (!responseContentType || !responseContentType.includes("application/json")) {
30
+ if (responseStatusCode === 504) {
31
+ throw new Error(API_TIMEOUT_ERROR);
32
+ }
33
+
34
+ const responseText = await response.text();
35
+ throw new Error(responseText);
36
+ }
37
+
26
38
  try {
27
39
  return await response.json();
28
40
  } catch (err) {
@@ -30,4 +42,4 @@ async function execute(data, token, options = {}) {
30
42
  }
31
43
  }
32
44
 
33
- module.exports = { execute, COULD_NOT_PARSE_JSON_RESPONSE_ERROR };
45
+ module.exports = { execute, COULD_NOT_PARSE_JSON_RESPONSE_ERROR, TOKEN_IS_REQUIRED_ERROR, API_TIMEOUT_ERROR };