Socket
Socket
Sign inDemoInstall

kinvey-flex-sdk

Package Overview
Dependencies
Maintainers
2
Versions
54
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

kinvey-flex-sdk - npm Package Compare versions

Comparing version 3.0.0 to 3.1.0

.travis.yml

27

CHANGELOG.md
## Changelog
### 3.1.0
* FLEX-270 Added graceful shutdown
* Now on ctrl-c, SIGTERM, SIGINT, or SIGKILL, the sdk will attempt to wait for in-process tasks to finish.
* Will time out and force-quit if all tasks aren't complete in 50 seconds
* Pressing ctrl-c, or sending SIGINT/SIGTERM/SIGKILL a second time will terminate the process immediately.
* FLEX-291 Remove lodash as a dependency
* FLEX-290 Changed destination property in body for sendPush to recipients
* Removed CoffeeScript as a dependency
* Updated code-task-receiver to 2.3.1
* Updated kinvey-datalink-errors to 0.3.2
### 3.0.0
* See README for migration guide
* BREAKING CHANGE: email and push modules now require a callback or promise handlers. They can no longer be executed as "fire and forget".
* BREAKING CHANGE: email and push modules now require a callback or promise handlers. They can no longer be executed as "fire and forget".
* FLEX-206 Added Promise support to Asynchronous flex-sdk modules

@@ -59,3 +70,3 @@ * dataStore

* Fixed top-level errors to return JSON, fixing the bug where an invalid shared secret would generate the wrong error
* Set maxSockets to 100 for both http and https agents
* Set maxSockets to 100 for both http and https agents

@@ -70,10 +81,10 @@ ### 2.0.1

* Added `setBody` and `setQuery` to data/function completion hanlder
* Added `useBl` option to userStore and dataStore. Set to `true` to enable business logic execution for a store request. Defaults to false.
* Added `useBl` option to userStore and dataStore. Set to `true` to enable business logic execution for a store request. Defaults to false.
* Added `useUserContext` option to userStore and dataStore. Set to `true` to execute the request under user's authentication context. Defaults to false.
* dataStore and authStore now default to using mastersecret credentials and not executing business logic
* Circular requests to userStore/dataStore (e.g. saving back to the sae collection in a post hook) now must not execute BL and must be executed under masterSecret credentials.
* Circular requests to userStore/dataStore (e.g. saving back to the sae collection in a post hook) now must not execute BL and must be executed under masterSecret credentials.
* Some internal refactoring
* DEPRECATED: Passing the entity directly in the `complete()` method. Will be removed in future version.
* DEPRECATED: useMasterSecret argument for userStore and dataStore. Stores now default to using master secret. Use `useUserContext` to use the context of the current user for dataStore or userStore requests.
* DEPRECATED: skipBl argument for userStore and dataStore. Stores now default to not executing business logic hooks in response to store requests. Use `useBl` to enable BL execution.
* DEPRECATED: useMasterSecret argument for userStore and dataStore. Stores now default to using master secret. Use `useUserContext` to use the context of the current user for dataStore or userStore requests.
* DEPRECATED: skipBl argument for userStore and dataStore. Stores now default to not executing business logic hooks in response to store requests. Use `useBl` to enable BL execution.

@@ -110,3 +121,3 @@ ### 1.2.0

### 0.5.0
* Added `modules` accessible to all handler methods via third argument (e.g. onInsert(request, complete, modules:
* Added `modules` accessible to all handler methods via third argument (e.g. onInsert(request, complete, modules:
* backendContext

@@ -176,2 +187,2 @@ * dataStore (including access to Service Object backed data)

### 0.1.0
* Initial Release
* Initial Release

@@ -1,2 +0,2 @@

// Copyright (c) 2016 Kinvey Inc.
// Copyright (c) 2018 Kinvey Inc.
//

@@ -3,0 +3,0 @@ // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

/**
* Copyright (c) 2016 Kinvey Inc.
* Copyright (c) 2018 Kinvey Inc.
*

@@ -26,2 +26,4 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

let terminated = false;
http.globalAgent.maxSockets = 100;

@@ -32,2 +34,4 @@ https.globalAgent.maxSockets = 100;

constructor(options, callback) {
let gracefulShutdownTimeout;
if (!callback && typeof options === 'function') {

@@ -58,2 +62,25 @@ callback = options;

function terminate(err) {
clearTimeout(gracefulShutdownTimeout);
if (err) {
console.log(`Shutdown Error: ${err}`);
process.exit(-1);
}
process.exit();
}
function shutdown() {
if (terminated) {
// non-graceful shutdown, requires two successive signals
console.log('\nForced quit!\n');
return terminate('Force quit!');
}
terminated = true;
console.log('Signal received, initiating graceful shutdown. Press ctrl-c or send SIGTERM/SIGKILL/SIGINT to force-quit immediately.');
gracefulShutdownTimeout = setTimeout(terminate, 50000);
receiver.stop((err) => terminate(err));
}
// TODO Remove legacy taskType values

@@ -109,2 +136,6 @@ const taskReceivedCallback = ((task, completionCallback) => {

});
process.on('SIGTERM', shutdown);
process.on('SIGKILL', shutdown);
process.on('SIGINT', shutdown);
}

@@ -111,0 +142,0 @@ }

/**
* Copyright (c) 2016 Kinvey Inc.
* Copyright (c) 2018 Kinvey Inc.
*

@@ -4,0 +4,0 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

/**
* Copyright (c) 2016 Kinvey Inc.
* Copyright (c) 2018 Kinvey Inc.
*

@@ -15,4 +15,2 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

const getProp = require('lodash.get');
const kinveyCompletionHandler = require('./kinveyCompletionHandler');

@@ -121,3 +119,3 @@ const kinveyErrors = require('kinvey-datalink-errors');

function process(task, modules, callback) {
if ((getProp(task, ['request', 'serviceObjectName'])) == null) {
if (task.request == null || task.request.serviceObjectName == null) {
const result = task.response;

@@ -141,3 +139,3 @@ result.body = kinveyErrors.generateKinveyError('NotFound', 'ServiceObject name not found');

} catch (e) {
const body = getProp(task, ['request', 'body'], null);
const body = task.request.body || null;
if (body !== null && typeof body !== 'object') {

@@ -155,3 +153,3 @@ const result = task.response;

} catch (error) {
const query = getProp(task, ['request', 'query'], null);
const query = task.request.query || null;
if (query !== null && typeof query !== 'object') {

@@ -158,0 +156,0 @@ const result = task.response;

/**
* Copyright (c) 2016 Kinvey Inc.
* Copyright (c) 2018 Kinvey Inc.
*

@@ -4,0 +4,0 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

/**
* Copyright (c) 2016 Kinvey Inc.
* Copyright (c) 2018 Kinvey Inc.
*

@@ -4,0 +4,0 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

/**
* Copyright (c) 2016 Kinvey Inc.
* Copyright (c) 2018 Kinvey Inc.
*

@@ -4,0 +4,0 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

/**
* Copyright (c) 2016 Kinvey Inc.
* Copyright (c) 2018 Kinvey Inc.
*

@@ -15,4 +15,2 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

const getProp = require('lodash.get');
const backendContext = require('./modules/backendContext');

@@ -78,3 +76,2 @@ const dataStore = require('./modules/dataStore');

const proxyURL = task.proxyURL;
const appMetadata = {

@@ -106,11 +103,8 @@ _id: task.appMetadata._id,

requestMetadata.securityContext = getSecurityContextString(
getProp(task.request.headers, ['authorization'], []),
appMetadata
);
requestMetadata.securityContext = getSecurityContextString(task.request.headers.authorization, appMetadata);
let useBSONObjectId = false;
const migrated = getProp(task, ['appMetadata', 'appMetadata', 'objectid_migration', 'status']);
if (migrated != null && migrated === 'done') {
useBSONObjectId = true;
if (task.appMetadata.maintenance && task.appMetadata.maintenance.objectid_migration) {
useBSONObjectId = (task.appMetadata.maintenance.objectid_migration.status !== 'done');
}

@@ -117,0 +111,0 @@

/**
* Copyright (c) 2016 Kinvey Inc.
* Copyright (c) 2018 Kinvey Inc.
*

@@ -4,0 +4,0 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

/**
* Copyright (c) 2016 Kinvey Inc.
* Copyright (c) 2018 Kinvey Inc.
*

@@ -4,0 +4,0 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

/**
* Copyright (c) 2016 Kinvey Inc.
* Copyright (c) 2018 Kinvey Inc.
*

@@ -4,0 +4,0 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

/**
* Copyright (c) 2016 Kinvey Inc.
* Copyright (c) 2018 Kinvey Inc.
*

@@ -4,0 +4,0 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

/**
* Copyright (c) 2016 Kinvey Inc.
* Copyright (c) 2018 Kinvey Inc.
*

@@ -4,0 +4,0 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

/**
* Copyright (c) 2016 Kinvey Inc.
* Copyright (c) 2018 Kinvey Inc.
*

@@ -15,4 +15,2 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

const has = require('lodash.has');
const getProp = require('lodash.get');
const moment = require('moment');

@@ -54,8 +52,8 @@ const BSON = require('bson').BSONPure;

if (!has(_entity, ['_acl'])) _entity._acl = {};
if (!has(_entity, ['_id'])) _entity._id = _createEntityId();
if (!has(_entity, ['_acl', 'creator'])) _entity._acl.creator = environmentId;
if (!has(_entity, ['_kmd'])) _entity._kmd = {};
if (!has(_entity, ['_kmd', 'ect'])) _entity._kmd.ect = currentTimeString;
if (!has(_entity, ['_kmd', 'lmt'])) _entity._kmd.lmt = currentTimeString;
if (!_entity._acl) _entity._acl = {};
if (!_entity._id) _entity._id = _createEntityId();
if (!_entity._acl.creator) _entity._acl.creator = environmentId;
if (!_entity._kmd) _entity._kmd = {};
if (!_entity._kmd.ect) _entity._kmd.ect = currentTimeString;
if (!_entity._kmd.lmt) _entity._kmd.lmt = currentTimeString;
}

@@ -67,35 +65,35 @@ }

function getCreator() {
return getProp(_entity, ['_acl', 'creator']);
return _entity._acl.creator;
}
function getReaders() {
return getProp(_entity, ['_acl', 'r'], []);
return _entity._acl.r || [];
}
function getWriters() {
return getProp(_entity, ['_acl', 'w'], []);
return _entity._acl.w || [];
}
function getReaderGroups() {
return getProp(_entity, ['_acl', 'groups', 'r'], []);
return _entity._acl.groups ? _entity._acl.groups.r || [] : [];
}
function getWriterGroups() {
return getProp(_entity, ['_acl', 'groups', 'w'], []);
return _entity._acl.groups ? _entity._acl.groups.w || [] : [];
}
function getReaderRoles() {
return getProp(_entity, ['_acl', 'roles', 'r'], []);
return _entity._acl.roles ? _entity._acl.roles.r || [] : [];
}
function getUpdateRoles() {
return getProp(_entity, ['_acl', 'roles', 'u'], []);
return _entity._acl.roles ? _entity._acl.roles.u || [] : [];
}
function getDeleteRoles() {
return getProp(_entity, ['_acl', 'roles', 'd'], []);
return _entity._acl.roles ? _entity._acl.roles.d || [] : [];
}
function addReader(userId) {
if (!(getProp(_entity, ['_acl', 'r']))) _entity._acl.r = [];
if (!_entity._acl.r) _entity._acl.r = [];
if (_entity._acl.r.indexOf(userId) === -1) _entity._acl.r.push(userId);

@@ -106,3 +104,3 @@ return aclFunctions;

function addWriter(userId) {
if (!(getProp(_entity, ['_acl', 'w']))) _entity._acl.w = [];
if (!_entity._acl.w) _entity._acl.w = [];
if (_entity._acl.w.indexOf(userId) === -1) _entity._acl.w.push(userId);

@@ -113,4 +111,4 @@ return this;

function addReaderGroup(groupId) {
if (!(getProp(_entity, ['_acl', 'groups']))) _entity._acl.groups = {};
if (!(getProp(_entity, ['_acl', 'groups', 'r']))) _entity._acl.groups.r = [];
if (!_entity._acl.groups) _entity._acl.groups = {};
if (!_entity._acl.groups.r) _entity._acl.groups.r = [];
if (_entity._acl.groups.r.indexOf(groupId) === -1) _entity._acl.groups.r.push(groupId);

@@ -121,4 +119,4 @@ return aclFunctions;

function addWriterGroup(groupId) {
if (!(getProp(_entity, ['_acl', 'groups']))) _entity._acl.groups = {};
if (!(getProp(_entity, ['_acl', 'groups', 'w']))) _entity._acl.groups.w = [];
if (!_entity._acl.groups) _entity._acl.groups = {};
if (!_entity._acl.groups.w) _entity._acl.groups.w = [];
if (_entity._acl.groups.w.indexOf(groupId) === -1) _entity._acl.groups.w.push(groupId);

@@ -129,4 +127,4 @@ return aclFunctions;

function addReaderRole(roleId) {
if (!(getProp(_entity, ['_acl', 'roles']))) _entity._acl.roles = {};
if (!(getProp(_entity, ['_acl', 'roles', 'r']))) _entity._acl.roles.r = [];
if (!_entity._acl.roles) _entity._acl.roles = {};
if (!_entity._acl.roles.r) _entity._acl.roles.r = [];
if (_entity._acl.roles.r.indexOf(roleId) === -1) _entity._acl.roles.r.push(roleId);

@@ -137,4 +135,4 @@ return aclFunctions;

function addUpdateRole(roleId) {
if (!(getProp(_entity, ['_acl', 'roles']))) _entity._acl.roles = {};
if (!(getProp(_entity, ['_acl', 'roles', 'u']))) _entity._acl.roles.u = [];
if (!_entity._acl.roles) _entity._acl.roles = {};
if (!_entity._acl.roles.u) _entity._acl.roles.u = [];
if (_entity._acl.roles.u.indexOf(roleId) === -1) _entity._acl.roles.u.push(roleId);

@@ -145,4 +143,4 @@ return aclFunctions;

function addDeleteRole(roleId) {
if (!(getProp(_entity, ['_acl', 'roles']))) _entity._acl.roles = {};
if (!(getProp(_entity, ['_acl', 'roles', 'd']))) _entity._acl.roles.d = [];
if (!_entity._acl.roles) _entity._acl.roles = {};
if (!_entity._acl.roles.d) _entity._acl.roles.d = [];
if (_entity._acl.roles.d.indexOf(roleId) === -1) _entity._acl.roles.d.push(roleId);

@@ -153,3 +151,3 @@ return aclFunctions;

function removeReader(userId) {
let userIx = (getProp(_entity, ['_acl', 'r'], [])).indexOf(userId);
let userIx = (_entity._acl.r || []).indexOf(userId);
while (userIx !== -1) {

@@ -163,3 +161,3 @@ _entity._acl.r.splice(userIx, 1);

function removeWriter(userId) {
let userIx = (getProp(_entity, ['_acl', 'w'], [])).indexOf(userId);
let userIx = (_entity._acl.w || []).indexOf(userId);
while (userIx !== -1) {

@@ -173,6 +171,6 @@ _entity._acl.w.splice(userIx, 1);

function removeReaderGroup(groupId) {
let groupIx = (getProp(_entity, ['_acl', 'groups', 'r'], [])).indexOf(groupId);
let groupIx = (_entity._acl.groups ? _entity._acl.groups.r || [] : []).indexOf(groupId);
while (groupIx !== -1) {
_entity._acl.groups.r.splice(groupIx, 1);
groupIx = _entity._acl.groups.r.indexOf(groupId);
groupIx = (_entity._acl.groups ? _entity._acl.groups.r || [] : []).indexOf(groupId);
}

@@ -183,8 +181,6 @@ return aclFunctions;

function removeWriterGroup(groupId) {
let writers = getProp(_entity, ['_acl', 'groups', 'w'], []);
let groupIx = writers.indexOf(groupId);
let groupIx = (_entity._acl.groups ? _entity._acl.groups.w || [] : []).indexOf(groupId);
while (groupIx !== -1) {
_entity._acl.groups.w.splice(groupIx, 1);
writers = getProp(_entity, ['_acl', 'groups', 'w'], []);
groupIx = writers.indexOf(groupId);
groupIx = (_entity._acl.groups ? _entity._acl.groups.w || [] : []).indexOf(groupId);
}

@@ -195,6 +191,6 @@ return aclFunctions;

function removeReaderRole(roleId) {
let roleIx = (getProp(_entity, ['_acl', 'roles', 'r'], [])).indexOf(roleId);
let roleIx = (_entity._acl.roles ? _entity._acl.roles.r || [] : []).indexOf(roleId);
while (roleIx !== -1) {
_entity._acl.roles.r.splice(roleIx, 1);
roleIx = _entity._acl.roles.r.indexOf(roleId);
roleIx = (_entity._acl.roles ? _entity._acl.roles.r || [] : []).indexOf(roleId);
}

@@ -205,8 +201,6 @@ return aclFunctions;

function removeUpdateRole(roleId) {
let updates = getProp(_entity, ['_acl', 'roles', 'u'], []);
let roleIx = updates.indexOf(roleId);
let roleIx = (_entity._acl.roles ? _entity._acl.roles.u || [] : []).indexOf(roleId);
while (roleIx !== -1) {
_entity._acl.roles.u.splice(roleIx, 1);
updates = getProp(_entity, ['_acl', 'roles', 'u'], []);
roleIx = updates.indexOf(roleId);
roleIx = (_entity._acl.roles ? _entity._acl.roles.u || [] : []).indexOf(roleId);
}

@@ -217,8 +211,6 @@ return aclFunctions;

function removeDeleteRole(roleId) {
let deletes = getProp(_entity, ['_acl', 'roles', 'd'], []);
let roleIx = deletes.indexOf(roleId);
let roleIx = (_entity._acl.roles ? _entity._acl.roles.d || [] : []).indexOf(roleId);
while (roleIx !== -1) {
_entity._acl.roles.d.splice(roleIx, 1);
deletes = getProp(_entity, ['_acl', 'roles', 'd'], []);
roleIx = deletes.indexOf(roleId);
roleIx = (_entity._acl.roles ? _entity._acl.roles.d || [] : []).indexOf(roleId);
}

@@ -225,0 +217,0 @@ return aclFunctions;

/**
* Copyright (c) 2016 Kinvey Inc.
* Copyright (c) 2018 Kinvey Inc.
*

@@ -50,3 +50,3 @@ * Licensed under the Apache License, Version 2.0 (the 'License'); you may not use this file except

json: {
destination: userEntities,
recipients: userEntities,
messageContent: message

@@ -53,0 +53,0 @@ },

/**
* Copyright (c) 2016 Kinvey Inc.
* Copyright (c) 2018 Kinvey Inc.
*

@@ -17,5 +17,2 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

const sift = require('sift');
const isEmpty = require('lodash.isempty');
const assign = require('lodash.assign');
const forEach = require('lodash.foreach');

@@ -35,2 +32,11 @@ const isArray = Array.isArray;

function isObjectEmpty(obj) {
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
return false;
}
}
return true;
}
function nested(obj, dotProperty, value) {

@@ -54,3 +60,3 @@ if (!dotProperty) {

constructor(options) {
options = assign({
options = Object.assign({
fields: [],

@@ -437,3 +443,3 @@ filter: {},

const members = Object.keys(this.filter);
forEach(members, member => {
members.forEach((member) => {
currentQuery[member] = this.filter[member];

@@ -539,7 +545,7 @@ delete this.filter[member];

if (!isEmpty(this.filter)) {
if (!isObjectEmpty(this.filter)) {
queryString.query = this.filter;
}
if (!isEmpty(this.fields)) {
if (this.fields.length > 0) {
queryString.fields = this.fields.join(',');

@@ -556,3 +562,3 @@ }

if (!isEmpty(this.sort)) {
if (!isObjectEmpty(this.sort)) {
queryString.sort = this.sort;

@@ -562,3 +568,3 @@ }

const keys = Object.keys(queryString);
forEach(keys, key => {
keys.forEach((key) => {
queryString[key] = typeof queryString[key] === 'string' ? queryString[key] : JSON.stringify(queryString[key]);

@@ -565,0 +571,0 @@ });

@@ -1,2 +0,2 @@

/** Copyright (c) 2016 Kinvey Inc.
/** Copyright (c) 2018 Kinvey Inc.
*

@@ -14,4 +14,2 @@ * Licensed under the Apache License, Version 2.0 (the 'License'); you may not use this file except

const getProp = require('lodash.get');
function requestContextModule(metadata) {

@@ -39,3 +37,3 @@ let string = null;

metadata.customRequestProperties = getProp(metadata, 'customRequestProperties', {});
metadata.customRequestProperties = metadata.customRequestProperties || {};

@@ -42,0 +40,0 @@ function getCustomRequestProperties() {

/**
* Copyright (c) 2016 Kinvey Inc.
* Copyright (c) 2018 Kinvey Inc.
*

@@ -4,0 +4,0 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

/**
* Copyright (c) 2016 Kinvey Inc.
* Copyright (c) 2018 Kinvey Inc.
*

@@ -4,0 +4,0 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

/**
* Copyright (c) 2016 Kinvey Inc.
* Copyright (c) 2018 Kinvey Inc.
*

@@ -4,0 +4,0 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except

@@ -1,2 +0,2 @@

Copyright 2016 Kinvey, Inc.
Copyright 2018 Kinvey, Inc.

@@ -438,3 +438,3 @@ Licensed under the Apache License, Version 2.0 (the "License");

Copyright 2016 Kinvey, Inc.
Copyright 2018 Kinvey, Inc.

@@ -441,0 +441,0 @@ Licensed under the Apache License, Version 2.0 (the "License");

{
"name": "kinvey-flex-sdk",
"version": "3.0.0",
"version": "3.1.0",
"description": "SDK for creating Kinvey Flex Services",

@@ -20,10 +20,4 @@ "engines": {

"bson": "0.4.23",
"kinvey-code-task-runner": "2.2.4",
"kinvey-datalink-errors": "0.3.0",
"lodash.forown": "4.2.0",
"lodash.get": "4.3.0",
"lodash.has": "4.4.0",
"lodash.isempty": "4.4.0",
"lodash.assign": "4.2.0",
"lodash.foreach": "4.5.0",
"kinvey-code-task-runner": "2.3.1",
"kinvey-datalink-errors": "0.3.2",
"moment": "2.21.0",

@@ -47,3 +41,6 @@ "request": "2.86.0",

"pretest": "./node_modules/.bin/eslint lib test",
"test": "mocha test/lib/modules/* test/lib/*",
"lint": "npm run pretest",
"test": "npm run test-unit && npm run test-integration",
"test-unit": "mocha test/unit/*/*",
"test-integration": "echo \"No integration tests available for the moment\"",
"test-core": "mocha test/lib/*",

@@ -65,4 +62,5 @@ "test-flex": "mocha test/lib/flex.test.js",

"test-tempobjectstore": "mocha test/lib/modules/tempObjectStore.test.js",
"test-userStore": "mocha test/lib/modules/userStore.test.js"
"test-userStore": "mocha test/lib/modules/userStore.test.js",
"test-npm-security": "npm audit"
}
}

@@ -0,1 +1,3 @@

[![Build Status](https://travis-ci.org/Kinvey/flex-sdk.svg?branch=master)](https://travis-ci.org/Kinvey/flex-sdk)
# Kinvey Flex SDK (beta)

@@ -2,0 +4,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc