knack-api-helper
Advanced tools
+79
-7
@@ -27,5 +27,7 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.KnackAPI = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ | ||
| this.urlBase = `https://api.knack.com/v1`; | ||
| this.remoteLogin = async function(settings = {email, password}){ | ||
| return await _fetch.one({ | ||
| url: `https://api.knack.com/v1/applications/${this.headers['X-Knack-Application-ID']}/session`, | ||
| url: `${this.urlBase}/applications/${this.headers['X-Knack-Application-ID']}/session`, | ||
| options: { | ||
@@ -65,3 +67,3 @@ method: 'POST', | ||
| const response = await _fetch.one({ | ||
| url: 'https://api.knack.com/v1/session/token', | ||
| url: `${this.urlBase}/session/token`, | ||
| options: { | ||
@@ -103,9 +105,11 @@ method: 'GET', | ||
| this.url = function(settings = {scene, view, object, recordId}){ | ||
| let url = ""; | ||
| let url = this.urlBase; | ||
| if(config.auth === 'view-based'){ | ||
| url = `https://api.knack.com/v1/pages/${settings.scene}/views/${settings.view}/records/`; | ||
| url += `/pages/${settings.scene}/views/${settings.view}/records/`; | ||
| } else if (config.auth === 'object-based'){ | ||
| url = `https://api.knack.com/v1/objects/${settings.object}/records/`; | ||
| url += `/objects/${settings.object}/records/`; | ||
| } | ||
| if(settings.recordId) url += settings.recordId; | ||
@@ -115,2 +119,10 @@ return url; | ||
| this.getRetries = function(retries) { | ||
| if(typeof retries === 'number'){ | ||
| return retries; | ||
| } else { | ||
| return 5; | ||
| } | ||
| } | ||
| this.setup = function(method, settings){ | ||
@@ -143,3 +155,3 @@ let url = ""; | ||
| const retries = typeof settings.retries === 'number' ? settings.retries : 5; | ||
| const retries = this.getRetries(settings.retries); | ||
| return {url, options, retries, helperData: settings.helperData}; | ||
@@ -272,2 +284,36 @@ | ||
| //API call to get data from a report view like pivot table, bar chart or similar. Only works with view-based auth | ||
| this.getFromReportView = async function(settings = {view, scene, sceneRecordId, helperData, retries}){ | ||
| //Check for errors in config, since it's a bit different to other API calls | ||
| if (config.auth !== 'view-based') throw new Error('getFromReportView() only works when using view-based auth'); | ||
| if (!settings.view || !settings.scene) throw new Error('getFromReportView() requires a view and scene. You did not specify one or both.'); | ||
| if (settings.recordId) throw new Error('getFromReportView() does not support recordId. Specify settings.sceneRecordId if you are trying to load a report on a child page that has the data source of "this page\'s record" or similar.'); | ||
| //Build the URL, which has a different format to other API calls | ||
| //All reports API calls take format of /pages/{scene}/views/{view}/report | ||
| //If the report is on a child page with data source of "this page's record", then we need to add query string of ?{sceneSlug}_id={sceneRecordId} so Knack knows what record to filter records by | ||
| //Eg /pages/scene_1/views/view_1/report?dashboard_id=63e1bfe1a978400745e3a736 | ||
| let url = `${this.urlBase}/scenes/${settings.scene}/views/${settings.view}/report`; | ||
| if(settings.sceneRecordId) { | ||
| const sceneSlug = await this.getSceneSlug(settings.scene); | ||
| url += `?${sceneSlug}_id=${settings.sceneRecordId}` | ||
| } | ||
| //Build the _fetch request object | ||
| const req = { | ||
| url, | ||
| options: { | ||
| method: 'GET', | ||
| headers: this.headers | ||
| }, | ||
| retries: this.getRetries(settings.retries), | ||
| helperData: settings.helperData | ||
| } | ||
| //Run the API call. | ||
| return await _fetch.one(req); | ||
| } | ||
| this.tools = { | ||
@@ -365,2 +411,28 @@ progressBar: { | ||
| //Utility function to get the current slug of a scene (eg dashboard) based on it's key (eg scene_21) using the Knack API | ||
| this.getSceneSlug = async function(sceneKey) { | ||
| const appDataUrl = `${this.urlBase}/applications/${this.headers['X-Knack-Application-ID']}`; | ||
| const appData = await _fetch.one({ | ||
| url: appDataUrl, | ||
| options: { | ||
| method: 'GET', | ||
| } | ||
| }); | ||
| const scenes = appData.json.application.scenes; | ||
| const scene = scenes.find(scene => scene.key === sceneKey); | ||
| if(!scene) throw new Error(`Scene with key ${sceneKey} not found, when trying to find corresponding slug (url). Could not continue.`); | ||
| const slug = scene.slug; | ||
| if(!slug) throw new Error(`Scene with key ${sceneKey} found, but no slug (url) found. Could not continue.`); | ||
| return slug; | ||
| } | ||
| function checkConfig(){ | ||
@@ -367,0 +439,0 @@ |
+4
-0
| # Knack-api-helper CHANGELOG | ||
| ## 2022/01/29 Version 2.2.3 -> 2.2.4 | ||
| * Added new method getFromReportView() the enables getting data from report view (when using view-based auth) | ||
| * Refactored knack-api-helper.js to support this, but there are no functionality changes to existing methods (get, post, put, delete, getMany, postMany, putMany, deleteMany, login, remoteLogin, validateSession) | ||
| ## 2022/09/16 Version 2.2.2 -> 2.2.3 | ||
@@ -4,0 +8,0 @@ * Fixed browser build (browser loadable file). Otherwise unchanged |
+79
-7
@@ -26,5 +26,7 @@ const _fetch = require('@callum.boase/fetch'); | ||
| this.urlBase = `https://api.knack.com/v1`; | ||
| this.remoteLogin = async function(settings = {email, password}){ | ||
| return await _fetch.one({ | ||
| url: `https://api.knack.com/v1/applications/${this.headers['X-Knack-Application-ID']}/session`, | ||
| url: `${this.urlBase}/applications/${this.headers['X-Knack-Application-ID']}/session`, | ||
| options: { | ||
@@ -64,3 +66,3 @@ method: 'POST', | ||
| const response = await _fetch.one({ | ||
| url: 'https://api.knack.com/v1/session/token', | ||
| url: `${this.urlBase}/session/token`, | ||
| options: { | ||
@@ -102,9 +104,11 @@ method: 'GET', | ||
| this.url = function(settings = {scene, view, object, recordId}){ | ||
| let url = ""; | ||
| let url = this.urlBase; | ||
| if(config.auth === 'view-based'){ | ||
| url = `https://api.knack.com/v1/pages/${settings.scene}/views/${settings.view}/records/`; | ||
| url += `/pages/${settings.scene}/views/${settings.view}/records/`; | ||
| } else if (config.auth === 'object-based'){ | ||
| url = `https://api.knack.com/v1/objects/${settings.object}/records/`; | ||
| url += `/objects/${settings.object}/records/`; | ||
| } | ||
| if(settings.recordId) url += settings.recordId; | ||
@@ -114,2 +118,10 @@ return url; | ||
| this.getRetries = function(retries) { | ||
| if(typeof retries === 'number'){ | ||
| return retries; | ||
| } else { | ||
| return 5; | ||
| } | ||
| } | ||
| this.setup = function(method, settings){ | ||
@@ -142,3 +154,3 @@ let url = ""; | ||
| const retries = typeof settings.retries === 'number' ? settings.retries : 5; | ||
| const retries = this.getRetries(settings.retries); | ||
| return {url, options, retries, helperData: settings.helperData}; | ||
@@ -271,2 +283,36 @@ | ||
| //API call to get data from a report view like pivot table, bar chart or similar. Only works with view-based auth | ||
| this.getFromReportView = async function(settings = {view, scene, sceneRecordId, helperData, retries}){ | ||
| //Check for errors in config, since it's a bit different to other API calls | ||
| if (config.auth !== 'view-based') throw new Error('getFromReportView() only works when using view-based auth'); | ||
| if (!settings.view || !settings.scene) throw new Error('getFromReportView() requires a view and scene. You did not specify one or both.'); | ||
| if (settings.recordId) throw new Error('getFromReportView() does not support recordId. Specify settings.sceneRecordId if you are trying to load a report on a child page that has the data source of "this page\'s record" or similar.'); | ||
| //Build the URL, which has a different format to other API calls | ||
| //All reports API calls take format of /pages/{scene}/views/{view}/report | ||
| //If the report is on a child page with data source of "this page's record", then we need to add query string of ?{sceneSlug}_id={sceneRecordId} so Knack knows what record to filter records by | ||
| //Eg /pages/scene_1/views/view_1/report?dashboard_id=63e1bfe1a978400745e3a736 | ||
| let url = `${this.urlBase}/scenes/${settings.scene}/views/${settings.view}/report`; | ||
| if(settings.sceneRecordId) { | ||
| const sceneSlug = await this.getSceneSlug(settings.scene); | ||
| url += `?${sceneSlug}_id=${settings.sceneRecordId}` | ||
| } | ||
| //Build the _fetch request object | ||
| const req = { | ||
| url, | ||
| options: { | ||
| method: 'GET', | ||
| headers: this.headers | ||
| }, | ||
| retries: this.getRetries(settings.retries), | ||
| helperData: settings.helperData | ||
| } | ||
| //Run the API call. | ||
| return await _fetch.one(req); | ||
| } | ||
| this.tools = { | ||
@@ -364,2 +410,28 @@ progressBar: { | ||
| //Utility function to get the current slug of a scene (eg dashboard) based on it's key (eg scene_21) using the Knack API | ||
| this.getSceneSlug = async function(sceneKey) { | ||
| const appDataUrl = `${this.urlBase}/applications/${this.headers['X-Knack-Application-ID']}`; | ||
| const appData = await _fetch.one({ | ||
| url: appDataUrl, | ||
| options: { | ||
| method: 'GET', | ||
| } | ||
| }); | ||
| const scenes = appData.json.application.scenes; | ||
| const scene = scenes.find(scene => scene.key === sceneKey); | ||
| if(!scene) throw new Error(`Scene with key ${sceneKey} not found, when trying to find corresponding slug (url). Could not continue.`); | ||
| const slug = scene.slug; | ||
| if(!slug) throw new Error(`Scene with key ${sceneKey} found, but no slug (url) found. Could not continue.`); | ||
| return slug; | ||
| } | ||
| function checkConfig(){ | ||
@@ -366,0 +438,0 @@ |
+1
-1
| { | ||
| "name": "knack-api-helper", | ||
| "version": "2.2.3", | ||
| "version": "2.2.4", | ||
| "description": "Methods for interacting with the Knack API using both view-based and object-based authentication", | ||
@@ -5,0 +5,0 @@ "main": "knack-api-helper.js", |
+111
-5
@@ -322,4 +322,5 @@ # KnackAPI | ||
| ## Record-related API calls | ||
| There are 8 types of record-related API calls (ie API calls that deal with records in your Knack database) supported by Knack-api-helper. These are: | ||
| ## Standard CRUD API calls | ||
| There are 8 types of API calls supported by knack-api-helper, for standard CRUD (Create, read, update, delete) of records in your Knack database. These are: | ||
| * `get` | ||
@@ -334,4 +335,4 @@ * `getMany` | ||
| ### Standard parameters for record-related API calls | ||
| All the record-related API calls share these common parameters. | ||
| ### Common parameters for Standard CRUD API calls | ||
| All the standard CRUD API calls share these common parameters. | ||
@@ -477,3 +478,3 @@ | Parameter | Type | Required? | Auth type applies to | Details | | ||
| `getMany` accepts the [Standard parameters for record-related API calls](#standard-parameters-for-record-related-api-calls). | ||
| `getMany` accepts the [Common parameters for Standard CRUD API calls](#common-parameters-for-standard-crud-api-calls). | ||
@@ -689,1 +690,106 @@ * Note: in the context of `getMany` (if using view-based authentication) the `view` parameter should point to a Knack app `view` that lists many records such as a grid, search or list view. | ||
| ``` | ||
| ## Special CRUD API calls | ||
| These methods deal with non-standard API calls to your Knack database. Non-standard means operations that are outside of normal create, read, update or delete of one/many records in your database. | ||
| These methods are less commonly used, but can be very useful. | ||
| They also may have less standard parameters or may have special requirements for usage (eg some only work with view-based authentication). | ||
| ### getDataFromReportView() | ||
| This method lets you query a Knack "report" view (pivot table, bar chart, pie chart, line chart or similar) to obtain consolidated / summarized data. | ||
| Important note: this method relies on view-based authentication, so knackAPI must be initialised with view-based authentication (it cannot be used with object-based). | ||
| `getDataFromReportView()` accepts SOME of the [Common parameters for Standard CRUD API calls](#common-parameters-for-standard-crud-api-calls) as listed below: | ||
| 1. `scene` (scene containing the report view) | ||
| 2. `view` (the report view to use for making the view-based API call. This may contain one or more charts. | ||
| 3. `helperData` (optional) | ||
| 4. `retries` (optional, defaults to 5) | ||
| It also supports one additional parameter: | ||
| | Parameter | Type | Required? | Details | | ||
| | --- | --- | --- | --- | | ||
| | sceneRecordId | string | No | The record ID to filter records by, if your report is situated on a child page that deals with one particular record (ie it has the data source of "records connected to this page's XXX record"). (example below) | | ||
| #### Example getDataFromReportView() request (without sceneRecordId) | ||
| This example references a report view on a top-level scene. Eg a report view summarising all "Project records". (The URL of the page in the live app does NOT contain a record ID eg `your-org.knack.com#your-app/projects/`). | ||
| This is the simplest usage of `getDataFromReportView()`. | ||
| The example has two charts within the report view. So `getDataFromReportView()` will return an array of two objects, one for each chart. | ||
| ```javascript | ||
| //Initialise knack-api-helper. You MUST use view-based auth to use getDataFromReportView() | ||
| const knackAPI = new KnackAPI({ | ||
| auth: 'view-based', | ||
| applicationId: "YOUR APPLICATION ID", | ||
| userToken: Knack.getUserToken() | ||
| }); | ||
| const reportDataResponse = await knackAPI.getFromReportView({ | ||
| view: 'view_6', | ||
| scene: 'scene_2' | ||
| }) | ||
| console.log(reportDataResponse.json); | ||
| //Expected output: | ||
| //An array of report objects, 1 per chart in your report view | ||
| reports: [ | ||
| //Example of 1 report view. | ||
| { | ||
| records: [ | ||
| //Structure of records depends on your report setup. Example: | ||
| { group_0: 'Some grouping', calc_0: '$123,000', raw_0: 123000}, | ||
| { group_0: 'Some other group', calc_0: '$456,000', raw_0: 456000}, | ||
| ], | ||
| filters: [ | ||
| //Structure of filters depends on your report setup. | ||
| { header: 'Some grouping' }, | ||
| { header: 'Some other group' }, | ||
| ], | ||
| summaries: [ | ||
| //Structure of summaries depends on your report setup. | ||
| {} | ||
| ] | ||
| }, | ||
| ] | ||
| ``` | ||
| #### Example getDataFromReportView() request (with sceneRecordId) | ||
| This example references a report view on a child page that deals with one particular record. | ||
| For example, in an app where Invoices are connected to Projects, and the report view is situated a child page dealing with project records. The report's data source appears as "Invoices connected to this page's Project". | ||
| (When viewing the live app, the URL of the page containing the report will include a record ID eg `your-org.knack.com#your-app/projects/63e1bfe1a978400745e3a735`, where `63e1bfe1a978400745e3a735` is the record ID of a Project record). | ||
| In this case, you need to specify the record ID of the Project record via `sceneRecordId` when calling the Knack API. This tells Knack which Invoice records to summarize. | ||
| ```javascript | ||
| //Initialise knack-api-helper. You MUST use view-based auth to use getDataFromReportView() | ||
| const knackAPI = new KnackAPI({ | ||
| auth: 'view-based', | ||
| applicationId: "YOUR APPLICATION ID", | ||
| userToken: Knack.getUserToken() | ||
| }); | ||
| const reportDataResponse = await knackAPI.getFromReportView({ | ||
| view: 'view_8', | ||
| scene: 'scene_3', | ||
| sceneRecordid: '63e1bfe1a978400745e3a735'//The record ID of the parent record (eg one Project record) | ||
| }) | ||
| console.log(reportDataResponse.json); | ||
| //Expected output: as for previous example. | ||
| ``` | ||
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
79084
16.32%847
14%792
15.45%9
-18.18%