@integration-app/sdk
Advanced tools
Comparing version 0.16.6 to 0.16.7
@@ -23,5 +23,5 @@ import Pusher from 'pusher-js'; | ||
export declare class IntegrationAppClient { | ||
private apiUri?; | ||
private uiUri?; | ||
private token; | ||
apiUri?: string; | ||
uiUri?: string; | ||
token: string; | ||
private pusher; | ||
@@ -28,0 +28,0 @@ private pusherChannels; |
@@ -6,10 +6,14 @@ import { DataFilter } from '../../data-filter'; | ||
filter?: DataFilter; | ||
value: any; | ||
value?: any; | ||
} | ||
export declare type CaseFormulaValue = CaseFormulaValueItem[]; | ||
export declare type CaseFormulaValue = { | ||
cases: CaseFormulaValueItem[]; | ||
default?: any; | ||
}; | ||
export declare class DataBuilderFormulaCase extends DataBuilderFormulaBase { | ||
value: CaseFormulaValue; | ||
constructor(value: CaseFormulaValue); | ||
constructor(value: CaseFormulaValueItem[] | CaseFormulaValue); | ||
getValue(context: DataBuilderContext): any; | ||
getSchema(variablesSchema: any): any; | ||
isValueValid(): boolean; | ||
} |
@@ -12,16 +12,26 @@ "use strict"; | ||
super(); | ||
this.value = value; | ||
this.type = _1.DataBuilderFormulaType.CASE; | ||
if (!Array.isArray(value)) { | ||
this.value = []; | ||
if (!value && !Array.isArray(value) && typeof value !== 'object') { | ||
this.value = { | ||
cases: [], | ||
default: undefined, | ||
}; | ||
} | ||
else if (Array.isArray(value)) { | ||
this.value = { | ||
cases: value, | ||
default: undefined, | ||
}; | ||
} | ||
else if (typeof value === 'object' && Array.isArray(value.cases)) { | ||
this.value = value; | ||
} | ||
} | ||
getValue(context) { | ||
if (!Array.isArray(this.value)) { | ||
var _a; | ||
if (!this.isValueValid()) | ||
return undefined; | ||
} | ||
for (const item of this.value) { | ||
if (!item || typeof item !== 'object') { | ||
for (const item of this.value.cases) { | ||
if (!item || typeof item !== 'object') | ||
continue; | ||
} | ||
if ((0, data_filter_1.doesMatchFilter)(context.variables, item.filter)) { | ||
@@ -31,17 +41,23 @@ return (0, _1.processValue)(item.value, context); | ||
} | ||
return (_a = (0, _1.processValue)(this.value.default, context)) !== null && _a !== void 0 ? _a : undefined; | ||
} | ||
getSchema(variablesSchema) { | ||
if (Array.isArray(this.value)) { | ||
const values = this.value | ||
.map((item) => item.value) | ||
.filter((value) => value !== undefined); | ||
const schemas = values.map((value) => (0, __1.buildDataSchema)(value, variablesSchema)); | ||
return (0, schema_builder_1.mergeSchemas)(schemas); | ||
} | ||
else { | ||
if (!this.isValueValid()) | ||
return undefined; | ||
const schemas = this.value.cases | ||
.map((item) => item.value) | ||
.filter((value) => value !== undefined) | ||
.map((value) => (0, __1.buildDataSchema)(value, variablesSchema)); | ||
if (this.value.default) { | ||
schemas.push((0, __1.buildDataSchema)(this.value.default, variablesSchema)); | ||
} | ||
return (0, schema_builder_1.mergeSchemas)(schemas); | ||
} | ||
isValueValid() { | ||
return (this.value && | ||
typeof this.value === 'object' && | ||
Array.isArray(this.value.cases)); | ||
} | ||
} | ||
exports.DataBuilderFormulaCase = DataBuilderFormulaCase; | ||
//# sourceMappingURL=case.js.map |
@@ -6,2 +6,3 @@ import { Connection } from '../connections'; | ||
import { CreateIntegrationRequest, UpdateIntegrationRequest } from './api'; | ||
import { ConnectorSpec } from '../connector-api'; | ||
export declare class IntegrationsAccessor { | ||
@@ -17,3 +18,8 @@ private client; | ||
constructor(client: IntegrationAppClient, idOrKey: string); | ||
getConnectorSpec(): Promise<ConnectorSpec>; | ||
createConnection({ parameters }: { | ||
parameters: any; | ||
}): Promise<Connection>; | ||
openNewConnection(): Promise<Connection>; | ||
connect(): Promise<Connection>; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.IntegrationAccessor = exports.IntegrationsAccessor = void 0; | ||
const tslib_1 = require("tslib"); | ||
const _1 = require("."); | ||
const iframe_1 = require("../iframe"); | ||
const accessors_1 = require("../accessors"); | ||
const url_join_1 = (0, tslib_1.__importDefault)(require("url-join")); | ||
class IntegrationsAccessor { | ||
@@ -25,3 +28,71 @@ constructor(client) { | ||
} | ||
async connect() { | ||
async getConnectorSpec() { | ||
return this.client.get(`/integrations/${this.idOrKey}/connector-spec`); | ||
} | ||
async createConnection({ parameters }) { | ||
const spec = await this.getConnectorSpec(); | ||
let iframeElement; | ||
if (spec.connectionMode === _1.ConnectionMode.IFRAME) { | ||
iframeElement = createIframeElement(); | ||
} | ||
return new Promise((resolve, reject) => { | ||
const connectionUrl = (0, url_join_1.default)(this.client.apiUri, `oauth/new/${this.idOrKey}`, `?token=${this.client.token}&connectionParameters=${JSON.stringify(parameters)}`); | ||
const urlObj = new URL(connectionUrl); | ||
const requestId = (Math.random() + 1).toString(36).substring(0, 12); | ||
const listenerFunc = async (event) => { | ||
const message = event.data || {}; | ||
if (message.source == 'integration.app' && | ||
message.requestId == requestId) { | ||
cleanup(); | ||
if (message.type == 'newConnectionCreated') { | ||
resolve(message.connection); | ||
} | ||
else if (message.type == 'newConnectionCancel') { | ||
resolve(null); | ||
} | ||
else if (message.type == 'newConnectionFailure') { | ||
reject(new Error(message.error)); | ||
} | ||
} | ||
}; | ||
let cancelCheckInterval; | ||
function cleanup() { | ||
clearInterval(cancelCheckInterval); | ||
window.removeEventListener('message', listenerFunc); | ||
} | ||
try { | ||
window.addEventListener('message', listenerFunc); | ||
urlObj.searchParams.append('requestId', requestId); | ||
if (iframeElement) { | ||
urlObj.searchParams.append('iframe', '1'); | ||
iframeElement.src = urlObj.toString(); | ||
} | ||
else { | ||
const height = Math.round(screen.height * 0.6); | ||
const width = Math.round(screen.width * 0.7); | ||
const top = Math.round(screen.height * 0.2); | ||
const left = Math.round(screen.height * 0.15); | ||
const popup = window.open(urlObj.toString(), null, `popup,width=${width},height=${height},left=${left},top=${top}`); | ||
setTimeout(() => { | ||
if (!popup) { | ||
cleanup(); | ||
reject({ | ||
message: 'Popup has been blocked', | ||
}); | ||
} | ||
}, 1000); | ||
cancelCheckInterval = setInterval(() => { | ||
if (popup === null || popup === void 0 ? void 0 : popup.closed) { | ||
cleanup(); | ||
resolve(null); | ||
} | ||
}, 1000); | ||
} | ||
} | ||
catch (e) { | ||
reject(e); | ||
} | ||
}); | ||
} | ||
async openNewConnection() { | ||
const uri = this.client.getEmbedUri(`/integrations/${this.idOrKey}/connection/connect`); | ||
@@ -35,4 +106,19 @@ return new Promise((resolve) => { | ||
} | ||
async connect() { | ||
return this.openNewConnection(); | ||
} | ||
} | ||
exports.IntegrationAccessor = IntegrationAccessor; | ||
function createIframeElement() { | ||
const iframeElement = document.createElement('iframe'); | ||
iframeElement.style.position = 'absolute'; | ||
iframeElement.style.top = '-100'; | ||
iframeElement.style.left = '-100'; | ||
iframeElement.style.width = '1'; | ||
iframeElement.style.height = '1'; | ||
iframeElement.style.border = 'none'; | ||
iframeElement.style.backgroundColor = 'transparent'; | ||
document.body.appendChild(iframeElement); | ||
return iframeElement; | ||
} | ||
//# sourceMappingURL=accessors.js.map |
{ | ||
"name": "@integration-app/sdk", | ||
"version": "0.16.6", | ||
"version": "0.16.7", | ||
"description": "JavaScript SDK for Integration.app", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -71,5 +71,5 @@ import Pusher, { Channel } from 'pusher-js' | ||
export class IntegrationAppClient { | ||
private apiUri?: string | ||
private uiUri?: string | ||
private token: string | ||
public apiUri?: string | ||
public uiUri?: string | ||
public token: string | ||
private pusher: Pusher | undefined | ||
@@ -76,0 +76,0 @@ private pusherChannels: Record<string, Channel> = {} |
@@ -14,3 +14,29 @@ import { DataBuilderFormulaType, getFormula } from '.' | ||
it('should find case formula in value', () => { | ||
// argument as object | ||
const formula = getFormula({ | ||
$case: { | ||
cases: [ | ||
{ | ||
filter: null, | ||
value: 'foo', | ||
}, | ||
], | ||
default: 'bar', | ||
}, | ||
}) | ||
expect(formula).toBeDefined() | ||
expect(formula).not.toBeNull() | ||
expect(formula.type).toEqual(DataBuilderFormulaType.CASE) | ||
expect((formula as DataBuilderFormulaCase).value).toEqual({ | ||
cases: [ | ||
{ | ||
filter: null, | ||
value: 'foo', | ||
}, | ||
], | ||
default: 'bar', | ||
}) | ||
// argument as array | ||
const formula2 = getFormula({ | ||
$case: [ | ||
@@ -23,11 +49,14 @@ { | ||
}) | ||
expect(formula).toBeDefined() | ||
expect(formula).not.toBeNull() | ||
expect(formula.type).toEqual(DataBuilderFormulaType.CASE) | ||
expect((formula as DataBuilderFormulaCase).value).toEqual([ | ||
{ | ||
filter: null, | ||
value: 'foo', | ||
}, | ||
]) | ||
expect(formula2).toBeDefined() | ||
expect(formula2).not.toBeNull() | ||
expect(formula2.type).toEqual(DataBuilderFormulaType.CASE) | ||
expect((formula2 as DataBuilderFormulaCase).value).toEqual({ | ||
cases: [ | ||
{ | ||
filter: null, | ||
value: 'foo', | ||
}, | ||
], | ||
default: undefined, | ||
}) | ||
}) | ||
@@ -63,2 +92,10 @@ | ||
expect(formula.getValue(context)).toEqual('objValue') | ||
const formula2 = new DataBuilderFormulaCase({ | ||
cases: [], | ||
default: { | ||
$var: '$.obj.objKey', | ||
}, | ||
}) | ||
expect(formula2.getValue(context)).toEqual('objValue') | ||
}) | ||
@@ -121,2 +158,31 @@ | ||
it('should use default value correctly', () => { | ||
const formula = new DataBuilderFormulaCase({ | ||
default: 'defaultValue', | ||
cases: [ | ||
{ | ||
filter: [ | ||
{ | ||
field: 'key', | ||
operator: 'is', | ||
value: 'notValue', | ||
}, | ||
], | ||
value: 'incorrectValue', | ||
}, | ||
{ | ||
filter: [ | ||
{ | ||
field: 'key', | ||
operator: 'is', | ||
value: 'anotherNotValue', | ||
}, | ||
], | ||
value: 'anotherIncorrectValue', | ||
}, | ||
], | ||
}) | ||
expect(formula.getValue(context)).toEqual('defaultValue') | ||
}) | ||
it('should combine schemas of all option', () => { | ||
@@ -138,5 +204,41 @@ const variablesSchema = { | ||
}, | ||
obj3: { | ||
type: 'object', | ||
properties: { | ||
obj3Key: { type: 'string' }, | ||
}, | ||
}, | ||
}, | ||
} | ||
const formula = new DataBuilderFormulaCase([ | ||
const formula = new DataBuilderFormulaCase({ | ||
cases: [ | ||
{ | ||
value: { | ||
$var: '$.obj', | ||
}, | ||
filter: [], | ||
}, | ||
{ | ||
value: { | ||
$var: '$.obj2', | ||
}, | ||
filter: [], | ||
}, | ||
], | ||
default: { | ||
$var: '$.obj3', | ||
}, | ||
}) | ||
expect(formula.getSchema(variablesSchema)).toEqual({ | ||
type: 'object', | ||
properties: { | ||
objKey: { type: 'string' }, | ||
obj2Key: { type: 'string' }, | ||
obj3Key: { type: 'string' }, | ||
}, | ||
}) | ||
// without default value | ||
const formula2 = new DataBuilderFormulaCase([ | ||
{ | ||
@@ -155,3 +257,3 @@ value: { | ||
]) | ||
expect(formula.getSchema(variablesSchema)).toEqual({ | ||
expect(formula2.getSchema(variablesSchema)).toEqual({ | ||
type: 'object', | ||
@@ -158,0 +260,0 @@ properties: { |
@@ -10,9 +10,14 @@ import { DataFilter, doesMatchFilter } from '../../data-filter' | ||
filter?: DataFilter | ||
value: any | ||
value?: any | ||
} | ||
export type CaseFormulaValue = CaseFormulaValueItem[] | ||
export type CaseFormulaValue = { | ||
cases: CaseFormulaValueItem[] | ||
default?: any | ||
} | ||
export class DataBuilderFormulaCase extends DataBuilderFormulaBase { | ||
constructor(public value: CaseFormulaValue) { | ||
public value: CaseFormulaValue | ||
constructor(value: CaseFormulaValueItem[] | CaseFormulaValue) { | ||
super() | ||
@@ -22,4 +27,14 @@ | ||
if (!Array.isArray(value)) { | ||
this.value = [] | ||
if (!value && !Array.isArray(value) && typeof value !== 'object') { | ||
this.value = { | ||
cases: [], | ||
default: undefined, | ||
} | ||
} else if (Array.isArray(value)) { | ||
this.value = { | ||
cases: value, | ||
default: undefined, | ||
} | ||
} else if (typeof value === 'object' && Array.isArray(value.cases)) { | ||
this.value = value | ||
} | ||
@@ -29,9 +44,7 @@ } | ||
getValue(context: DataBuilderContext) { | ||
if (!Array.isArray(this.value)) { | ||
return undefined | ||
} | ||
for (const item of this.value) { | ||
if (!item || typeof item !== 'object') { | ||
continue | ||
} | ||
if (!this.isValueValid()) return undefined | ||
for (const item of this.value.cases) { | ||
if (!item || typeof item !== 'object') continue | ||
if (doesMatchFilter(context.variables, item.filter)) { | ||
@@ -41,17 +54,28 @@ return processValue(item.value, context) | ||
} | ||
return processValue(this.value.default, context) ?? undefined | ||
} | ||
getSchema(variablesSchema) { | ||
if (Array.isArray(this.value)) { | ||
const values = this.value | ||
.map((item) => item.value) | ||
.filter((value) => value !== undefined) | ||
const schemas = values.map((value) => | ||
buildDataSchema(value, variablesSchema), | ||
) | ||
return mergeSchemas(schemas) | ||
} else { | ||
return undefined | ||
if (!this.isValueValid()) return undefined | ||
const schemas = this.value.cases | ||
.map((item) => item.value) | ||
.filter((value) => value !== undefined) | ||
.map((value) => buildDataSchema(value, variablesSchema)) | ||
if (this.value.default) { | ||
schemas.push(buildDataSchema(this.value.default, variablesSchema)) | ||
} | ||
return mergeSchemas(schemas) | ||
} | ||
isValueValid() { | ||
return ( | ||
this.value && | ||
typeof this.value === 'object' && | ||
Array.isArray(this.value.cases) | ||
) | ||
} | ||
} |
import { Connection } from '../connections' | ||
import { FindIntegrationsQuery, FindIntegrationsResponse, Integration } from '.' | ||
import { | ||
ConnectionMode, | ||
FindIntegrationsQuery, | ||
FindIntegrationsResponse, | ||
Integration, | ||
} from '.' | ||
import { IntegrationAppClient } from '..' | ||
@@ -7,2 +12,4 @@ import { openIframe } from '../iframe' | ||
import { CreateIntegrationRequest, UpdateIntegrationRequest } from './api' | ||
import { ConnectorSpec } from '../connector-api' | ||
import urljoin from 'url-join' | ||
@@ -32,3 +39,96 @@ export class IntegrationsAccessor { | ||
async connect(): Promise<Connection> { | ||
async getConnectorSpec(): Promise<ConnectorSpec> { | ||
return this.client.get(`/integrations/${this.idOrKey}/connector-spec`) | ||
} | ||
async createConnection({ parameters }): Promise<Connection> { | ||
const spec = await this.getConnectorSpec() | ||
let iframeElement | ||
if (spec.connectionMode === ConnectionMode.IFRAME) { | ||
iframeElement = createIframeElement() | ||
} | ||
return new Promise((resolve, reject) => { | ||
const connectionUrl = urljoin( | ||
this.client.apiUri, | ||
`oauth/new/${this.idOrKey}`, | ||
`?token=${this.client.token}&connectionParameters=${JSON.stringify( | ||
parameters, | ||
)}`, | ||
) | ||
const urlObj = new URL(connectionUrl) | ||
const requestId = (Math.random() + 1).toString(36).substring(0, 12) | ||
const listenerFunc = async (event: any) => { | ||
const message = event.data || {} | ||
if ( | ||
message.source == 'integration.app' && | ||
message.requestId == requestId | ||
) { | ||
cleanup() | ||
if (message.type == 'newConnectionCreated') { | ||
resolve(message.connection) | ||
} else if (message.type == 'newConnectionCancel') { | ||
resolve(null) | ||
} else if (message.type == 'newConnectionFailure') { | ||
reject(new Error(message.error)) | ||
} | ||
} | ||
} | ||
let cancelCheckInterval: any | ||
function cleanup() { | ||
clearInterval(cancelCheckInterval) | ||
window.removeEventListener('message', listenerFunc) | ||
} | ||
try { | ||
window.addEventListener('message', listenerFunc) | ||
urlObj.searchParams.append('requestId', requestId) | ||
if (iframeElement) { | ||
urlObj.searchParams.append('iframe', '1') | ||
iframeElement.src = urlObj.toString() | ||
} else { | ||
const height = Math.round(screen.height * 0.6) | ||
const width = Math.round(screen.width * 0.7) | ||
const top = Math.round(screen.height * 0.2) | ||
const left = Math.round(screen.height * 0.15) | ||
const popup = window.open( | ||
urlObj.toString(), | ||
null, | ||
`popup,width=${width},height=${height},left=${left},top=${top}`, | ||
) | ||
setTimeout(() => { | ||
if (!popup) { | ||
cleanup() | ||
reject({ | ||
message: 'Popup has been blocked', | ||
}) | ||
} | ||
}, 1000) | ||
cancelCheckInterval = setInterval(() => { | ||
if (popup?.closed) { | ||
cleanup() | ||
resolve(null) | ||
} | ||
}, 1000) | ||
} | ||
} catch (e) { | ||
reject(e) | ||
} | ||
}) | ||
} | ||
/** | ||
* Show connection UI to your user. | ||
* Returns a promise that resolves to a new Connection object or | ||
* null if the user cancels the connection flow. | ||
*/ | ||
async openNewConnection(): Promise<Connection> { | ||
const uri = this.client.getEmbedUri( | ||
@@ -44,2 +144,22 @@ `/integrations/${this.idOrKey}/connection/connect`, | ||
} | ||
/** | ||
* @deprecated - use openNewConnection instead | ||
*/ | ||
async connect(): Promise<Connection> { | ||
return this.openNewConnection() | ||
} | ||
} | ||
function createIframeElement(): HTMLIFrameElement { | ||
const iframeElement = document.createElement('iframe') | ||
iframeElement.style.position = 'absolute' | ||
iframeElement.style.top = '-100' | ||
iframeElement.style.left = '-100' | ||
iframeElement.style.width = '1' | ||
iframeElement.style.height = '1' | ||
iframeElement.style.border = 'none' | ||
iframeElement.style.backgroundColor = 'transparent' | ||
document.body.appendChild(iframeElement) | ||
return iframeElement | ||
} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
3520176
45914