
Research
Security News
Malicious PyPI Package Exploits Deezer API for Coordinated Music Piracy
Socket researchers uncovered a malicious PyPI package exploiting Deezer’s API to enable coordinated music piracy through API abuse and C2 server control.
@axway/api-builder-sdk
Advanced tools
A plugin SDK for implementing custom flow-nodes for API Builder flows.
To get started with API Builder plugin development, use the @axway/api-builder CLI to generate a new plugin project.
npx @axway/api-builder plugin init myplugin
cd api-builder-plugin-myplugin
npm test
You created your first API Builder plugin! The CLI generated an example flow-node called "Hello World" that creates greeting based on provided name. You can use this guide to modify it to create your own custom flow-node. To get you started you can have a look at our collection of examples.
You may be interested in contributing your own flow-nodes to the wider API Builder community. While you can choose to keep your flow-nodes private, there are a lot of benefits to making them freely available to the API Builder community as an open source initiative. If you do not want to "own" the source, you can contribute them to api-builder-extras. If you would like your component to appear in the Components list in the UI, we would be happy to review your component and add it to the list. You can email the API Builder team at API.Builder.Team@axway.com.
The API Builder plugin is an npm module. To use the plugin, you must install the plugin as a dependency of an existing API Builder project. If you do not have a project, refer to the API Builder Getting Started Guide. There are several ways to install a plugin as a dependency (for a complete list see npm-install):
Managing separate modules as dependencies requires a basic understanding of npm that is not covered by this guide (see this guide for more information).
In order to install a plugin from npm as a dependency, it must first be published to npm (see npm-publish). Run the npm install
command to install the plugin as a dependency of an existing API Builder project. This is the best way to manage plugin dependencies.
cd my-existing-api-builder-project
npm install api-builder-plugin-myplugin
npm start
Assuming your projects all share the same root folder, you can install the plugin directly from source. Note that this is going to create a copy your plugin in the node_modules
directory. So, if you modify your plugin, then you will need to run the install command again (you can avoid this by using npm-link).
cd my-existing-api-builder-project
npm install ../api-builder-plugin-myplugin
npm start
It is possible to create and manage plugins directly from your API Builder project. It is very similar to installing a plugin from a relative directory, but it has some advantages in that it will share the same source as your project. However, like the relative directory, it still requires that you run npm install
, but you will only need to do this once because npm will create a link for you (see npm-link).
cd my-existing-api-builder-project
npm install ./api-builder-plugin-myplugin
npm start
├───package.json
├───src/
│ ├───actions.js
│ ├───flow-nodes.yml
│ ├───icon.svg
│ ├───index.js
└───test/
└───test.js
File name | Description |
---|---|
package.json | This is your module package description file. You should modify it to suit your module. |
src/actions.js | This file contains the actual JavaScript implementations of the methods defined in src/flow-nodes.yml . You will add your own method implementations here. |
src/flow-nodes.yml | Defines your flow-node. You will modify to add your own flow-node and methods. |
src/icon.svg | The icon file that is used in the UI. Supports image formats: bmp, jpeg, png, gif, tiff, or svg. |
src/index.js | Exports the API Builder plugin with a function called getPlugin . Edit this file if you wish to make use of some advanced features, like maintaining state. |
test/test.js | A mocha test suite. You should ensure all of your actions are adequately tested. |
The API Builder plugin for flow-nodes is configured using a YAML file called flow-nodes.yaml
within each project. The flow-nodes.yaml
file defines a structure that determines:
To get started, you can modify the example generated by the CLI. You may first want to change the name, icon or description of the example flow-node.
flow-nodes:
hello2:
name: Hello World
icon: icon.svg
description: Example flow-node to say hello.
category: general
Then, you may want to change the method or change the method parameters, or JSON schema of the parameters, or the outputs. Finally, write your JavaScript in the action function.
Flow-nodes utilize JSON schema to describe the acceptable values for various inputs and outputs. For simple parameters, this might just be one of the standard data types, e.g. type: string
.
Below are some example schema
. Additional examples can be found here.
# The value must be a string. The standard types are:
# null, boolean, object, array, number, string
type: string
# The value should be a boolean. The `default` is documentation
# purposes only and has to be handled in code.
type: boolean
default: true
# The value must be string or null
oneOf:
- type: string
- type: null
# The value must be a string and either "foo" or "bar"
type: string
enum:
- foo
- bar
# The value must be string and match a regex pattern
type: string
pattern: "v[0-9]+"
# The value must be string and is a multiline input format.
# Formats with special UI: multiline, javascript, mustache
type: string
format: multiline
# The value must be an array containing strings.
type: array
items:
type: string
# The value must be an array containing numbers.
# Limits the minimum number of items of that array to at least 1 and the maximum to 10.
type: array
items:
type: number
minItems: 1
maxItems: 10
The flow-nodes
key is the top-most element in the flow-nodes.yml
file. A flow-node specification begins with a unique key beneath flow-nodes
.
A flow-node is really just a container for a number of related functions. Each flow-node will correlate to a single UI element and icon that can be utilized within the API Builder flow editor. You can define multiple flow-nodes in the same plugin project, but generally speaking, it is more advisable to have a single-purpose plugin that defines one flow-node.
flow-nodes:
myplugin:
name: My Plugin
icon: icon.svg
description: My plugin is awesome.
category: general
methods:
# ...
The following table lists the attributes available when defining a flow-node:
Keyword | Required | Description |
---|---|---|
name | yes | A friendly name for your flow-node. This is how it will appear in the UI. Defaults to the flow-node key. |
icon | yes | An icon file for the UI. Supports formats: bmp, jpeg, png, gif, tiff, or svg. The file must be relative to the flow-nodes.yml file. The height and width of the icon should be equal (e.g. around 80px ). Using svg allows the icon to scale cleanly. |
description | yes | A summary of what the flow-node supports. |
category | yes | The category to which your flow-node should belong. |
methods | yes | A set of method definitions. |
A method defines an operation, its input parameters, and its outputs. The method is identified by a unique key below the flow-node methods
attribute.
name
in the UI flow-node configuration panel.actions.js
file. If you rename the method in flow-nodes.yml
, you should also rename it in actions.js
.methods:
getSomething:
name: Gets something
description: Gets something from somewhere
parameters:
# ...
outputs:
# ...
The following table lists the attributes available when defining a method.
Keyword | Required | Description |
---|---|---|
name | yes | A friendly name for your method. This is how it will appear in the UI. |
description | yes | A summary of the method. |
parameters | no | A set of unique parameter definitions. |
returns | see Description | Defines the value that is returned from your action method. If used, you must also use throws , and you cannot use outputs . You must use returns and throws or outputs . |
throws | see Description | Defines the Error that may be thrown from your action method. If used, you must also use returns , and you cannot use outputs . You must use returns and throws or outputs . |
outputs | see Description | A set of unique output definitions. If used, you cannot use returns and throws . You must use returns and throws or outputs . |
A parameter defines an input to the method's action function. The parameter is identified by a unique key below the method's parameters
attribute.
The parameter key is used when writing the flow-node action. Typically, the parameter key should be simple property identifier (i.e. A-Z characters), otherwise it will be difficult to use it.
group
), then alphabetically by parameter group
.required: true
), then alphabetically by parameter key.parameters:
username:
name: Username
description: The user name.
required: true
initialType: string
schema:
type: string
Keyword | Required | Description |
---|---|---|
name | yes | The friendly name of the parameter. |
description | yes | A description of the parameter. |
required | yes | Specifies that the parameter is required. |
initialType | no | The initial type to display by default in the UI flow-node configuration panel for this parameter. Allowed values are: object , array , string , selector , null , boolean and number . The default is selector . |
group | no | A group name to which the parameter belongs, e.g. "Advanced". By default, all parameters are ungrouped. The group name, "Authorization" is reserved for authorization parameters. |
multilineWrapper | no | Defines the before and after text that surrounds the user-provided parameter value in the UI text editor that gives context (e.g. that the user is defining a function) and prevents users from editing the before and after parts. |
schema | yes | A JSON schema that describes the acceptable value for the input parameter. |
The multilineWrapper
parameter option provides user-context in the UI when editing the parameter value. It gives context (e.g. that the user is defining a function), and prevents the users from editing the before
and after
part of the wrapper. A complete wrapper should use newlines for the best effect. The before
text would trail with a newline, and the after
text would lead with a newline. For example, to achieve an array input so that the user does not have to write the leading "[" or trailing "]":
options:
multilineWrapper:
before: "[\n"
after: "\n]"
When defining a multilineWrapper
parameter option, the following table lists the attributes that are available:
Keyword | Required | Description |
---|---|---|
before | yes | The leading text. The text should trail with a newline. |
after | yes | The trailing text. The text should lead with a newline. |
The result will be a UI where the leading before
and trailing after
will not be editable by the user, but provides necessary context while editing. For example:
[
...
]
The authorization parameters follow the same rules as regular parameters, save that an authorization parameter must be part of the "Authorization" group. The authorization parameter key is used when writing the flow-node action, so typically, the authorization parameter key should be simple property identifier (i.e. A-Z characters), otherwise it will be difficult to use it. There is no limit to the number of authorizations that can be defined.
parameters:
oauth2:
description: oAuth2 authorization.
group: Authorization
required: true
schema:
type: object
Keyword | Required | Description |
---|---|---|
description | yes | A description of the authorization. |
group | yes | The 'Authorization' group indicates this parameter is an authorization parameter. |
required | yes | Specifies that the authorization parameter is required. Defaults to true . |
schema | yes | A JSON schema that describes the acceptable value for the authorization parameter. |
The returns key defines the successful output of the method's action function, for all possible value(s) that are returned from the function. This correlates to the "Next" output of the Flow editor. If using returns
, you must also use throws.
returns:
name: Next
description: The operation was successful.
context: $.hello
schema:
type: string
Keyword | Required | Description |
---|---|---|
name | yes | A friendly name for the "Next" output of the flow-node. This is how it will appear in the Flow editor. |
description | yes | Describes the output value. |
context | no | A JSON path expression used to update the runtime context. For example, $.value . |
schema | no | A JSON schema that describes the output value. |
The throws key defines the error output of the method's action function, for Error exceptions that are thrown from the function. This correlates to the "Error" output of the Flow editor. If using throws
, you must also use returns.
throws:
name: Error
description: An unexpected error was encountered.
context: $.error
schema:
type: string
Keyword | Required | Description |
---|---|---|
name | yes | A friendly name for the "Error" output of the flow-node. This is how it will appear in the Flow editor. |
description | yes | Describes the output value. |
context | no | A JSON path expression used to update the runtime context. For example, $.value . |
schema | no | A JSON schema that describes the output value. |
The outputs key is an alternative way that the action method can be resolved, instead of using returns and throws. Each output can be thought of as an event that is triggered when the flow-node resolves at runtime.
However, using outputs should be discouraged because having multiple outputs complicates the flow-editor. We have plans to simplify the flow, and outputs are on our radar as usability issues. All possible return values can be sufficiently expressed using returns and throws, and we encourage you to do so.
Typically, successful outputs should be listed first, e.g. next
, and error outputs should be listed last, e.g. error
.
name
in the Flow editor's flow-node configuration panel.callback
function is stored in the context
at runtime.Error
in your error
outputs.outputs:
next:
name: Next
description: Success
context: $.value
noResult:
name: No Result
description: No result found
context: $.noResult
error:
name: Error
description: Something happened
context: $.error
To use the next
output, you just return as normal.
async function getSomething(params, options) {
return 'something';
}
To use the error
output, you would throw an Error.
async function getSomething(params, options) {
throw new Error('something');
}
To use the noResult
output, you would use the setOutput
function that is passed through options
, giving it the output key that you wish to invoke, and then return as normal.
async function getSomething(params, { setOutput }) {
setOutput('noResult');
return 'something';
}
Keyword | Required | Description |
---|---|---|
name | yes | A friendly name for the output of the flow-node. This is how it will appear in the Flow editor. |
description | yes | Describes the output value. |
context | no | A JSON path expression used to update the runtime context. For example, $.value . |
schema | no | A JSON schema that describes the output value. |
An action is a JavaScript function implementation that is defined in the actions.js
file. It must be exported with the same key as the flow-node method key defined in the flow-nodes.yaml
file.
async function getSomething(params, options) {
# ...
}
module.exports = {
getSomething
};
The first argument, params
contains the all of input parameters that are necessary to invoke the action. If any input parameter fails to resolve, they will not be passed into the action method, even if they were required. It is up to the action method to enforce required parameters, or to choose defaults when they are not defined.
The flow-node input parameters, can be accessed using the same parameter key as was defined in the flow-node method (e.g. params.username
).
return
from the function with the value intended to be returned from the default output.function getSomething(params, options) {
if (params.username) {
throw new Error('invalid username');
}
return { user: true };
}
The second argument, options
contains additional data. options.logger
provides access to the API Builder logging capabilities. It is used to log at the desired level (e.g. options.logger.error('...')
).
options.pluginConfig
is the user-configuration for this plugin that is loaded by the API Builder runtime in getPlugin
. This is made available to the action method by passing an option of the same name to the SDK constructor: new SDK({ pluginConfig })
.
options.pluginContext
could be used to share context between actions. For example you could share context between all plugin actions and getPlugin
- via the sdk.load(file, actions, { pluginContext })
. This is useful for storing any stateful information which may be required by all actions loaded from a file. Alternatively, you could set individual context on a per action basis by passing it in directly to the action(actions.hello, { pluginContext })
for those actions that really need it.
options.setOutput
allows you to return from a custom output other than next
. See below:
Actions may return a value, or a Promise
which resolves or rejects. Actions my also throw errors.
Any thrown error will result in the error
output being invoked in the flow, and returned values will invoke next
.
If a flow-node does not define the next
output, returning from the action will invoke the first defined output.
If a flow-node does not define the error
output, throwing from the function will result in the flow terminating. This is why it is always recommended to include an error
output in your flow-node.
Flow-nodes can have additional outputs, other than the conventional next
and error
, but this is discouraged. If additional outputs are required, then options.setOutput
can be used to return using a non-conventional output.
Triggers a custom output in the flow. Use this when you want to route to a non-conventional output other than next
or error
.
Param | Type | Default | Description |
---|---|---|---|
output | string | The name of the output to trigger. Cannot be 'error'. | |
value | * | The value to resolve with. |
Returns: *
- The value
that was passed as a parameter.
const value = encode(params.data);
return options.setOutput('encoded', value);
Generally speaking, your flow-node actions should be stateless, and not rely on global state. It makes it much easier to write and test. However, there are times when a flow-node may need to depend on state. For example, if it maintains a connection. For that, you can create and set an external context by passing it into the options
of sdk.load()
to maintain state. Later, the context can be accessed from the options
of your actions.
You can add a context in the getPlugin
function in index.js
. Note that if the getPlugin
method throws an exception, then API Builder will exit. While you may think that you want that to happen, consider the users of your flow-node. If they install your plugin through the UI, and it requires some external configuration that have not been provided (e.g. credentials), then you will cause API Builder to exit, and that is not a good experience. Therefore, getPlugin
should not throw exceptions.
Your flow-node actions have to deal with the state. For example, if the context maintains a connection, then your action methods need to test the state, and if disconnected, try to reconnect. If reconnect fails, then your action should fail (e.g. by throwing an Error). Let the flow designer that is using your flow-node decide on how deal with the connection issue (e.g. by sending an alert, or by returning a 500).
You should also handle restart in getPlugin
. If your context depends on configuration, which can change between restarts, then you should reset the state so that you plugin uses the new configuration.
Param | Type | Default | Description |
---|---|---|---|
file | string | The filename to load. | |
actions | Object | An object where each key name corresponds to a method key defined in the specification. | |
options | Object | The plugin options. | |
options.pluginContext | * | The plugin context that will be passed to all actions passed to this load method. |
// index.js
class Manager {
connect(username, password) { }
disconnect() { }
isConnected() {}
}
async function getPlugin(pluginConfig, options) {
const sdk = new SDK({ pluginConfig });
// Store any configuration now because they will not be available
// outside of this function.
const manager = new Manager();
try {
manager.disconnect();
} catch (ex) {
// Handle this. Do *not* throw exceptions from `getPlugin`.
options.logger.error('Failed to disconnect', ex.stack);
}
try {
manager.connect(pluginConfig.username, pluginConfig.password);
} catch (ex) {
// Handle this. Do *not* throw exceptions from `getPlugin`.
options.logger.error('Failed to connect', ex.stack);
}
const options = {
pluginContext: manager
};
sdk.load(path.resolve(__dirname, 'flow-nodes.yml'), actions, options);
return sdk.getPlugin();
}
// actions.js
async function hello(params, { logger, pluginConfig, pluginContext }) {
const { name } = params;
const manager = pluginContext;
if (!manager.isConnected()) {
// if this throws, then it will trigger the `error` output,
// which allows the flow designer to handle the error.
manager.connect(pluginConfig.username, pluginConfig.password);
}
return `Hello ${name}`;
}
The SDK comes a utility to help test your flow-node, MockRuntime
.
const { MockRuntime } = require('@axway/api-builder-sdk');
Your plugin exports the getPlugin
function in index.js
. This will be required in your unit-tests.
const getPlugin = require('../src');
The plugin will be loaded and invoked by the API Builder runtime, so it is necessary to use MockRuntime
to emulate this for unit-testing.
const plugin = await MockRuntime.loadPlugin(getPlugin);
The runtime instance has a validate
function that ensures the flow-node adheres to the schema.
it('should define valid flownodes', () => {
// if this is invalid, it will throw and fail
plugin.validate();
});
Then you can use getFlowNode
to obtain a handle to your flow-node and invoke it with various arguments, checking the response as appropriate.
it('should succeed with valid argument', async () => {
const flowNode = plugin.getFlowNode('myplugin');
const result = await flowNode.getSomething({ username: 'jbloggs' });
expect(result.callCount).to.equal(1);
expect(result.output).to.equal('next');
expect(result.args).to.equal([ null, { user: true }]);
expect(result.context).to.deep.equal({ something: { user: true } });
});
In some cases, your flow-node may require credentials in addition to the standard parameters. They are treated as normal parameters and are passed along with the rest with the params as follows:
it('should succeed with expected arguments', async () => {
const flowNode = runtime.getFlowNode('myplugin');
const params = {
name: 'bob',
key: '1234' // The authorization parameter
};
const result = await flowNode.getSomething(params);
const expected = {
name: 'bob',
key: '1234'
};
expect(result.callCount).to.equal(1);
expect(result.output).to.equal('next');
expect(result.args).to.deep.equal([ null, expected ]);
expect(result.context).to.deep.equal({ next: expected });
});
An async function that mocks the API Builder runtime that is used for testing flow-nodes. Pass it the getPlugin
function from index.js
. It resolves to a plugin
that is suitable for testing.
const plugin = await MockRuntime.loadPlugin(getPlugin);
Validates the flow-nodes to ensure it adheres to the schema.
Returns the IDs, in alphabetical order, of each flow-node within the plugin.
Obtains a flow-node instance suitable for testing. The actions.js
methods are bound to the object instance as asynchronous functions. For example, if you have an action getSomething
:
const flowNode = plugin.getFlowNode('myplugin');
const result = await flowNode.getSomething({ username: 'jbloggs' });
The number of times the output callback
was called.
The value that the action returned or resolved with.
If testing an action which has not been written using the SDK, this is the value of the second argument that was passed to the callback
function.
outputs(undefined, value);
If a callback
output was called, it is the name of the output that was called, e.g. "next"
. If the default callback
was called, this value is undefined
.
To debug the API Builder runtime, you can temporarily add a debugger
statement (just remember to remove it after you are done). Depending on how you decided to install the plugin, you may need to run npm install after adding the debugger
statement. It is recommended to use npm-link to make this process easier.
function getSomething(params, callback) {
debugger;
}
Then, you can run npm start
with additional arguments that will instruct Node.js to wait for a debugger to attach. In you API Builder project directory, execute:
npm start -- --inspect-brk
Then attach using a JavaScript debugger. We recommend using Chrome. Browse to:
chrome://inspect/#devices
And then click on the link Open dedicated DevTools for Node. Once attached, you can invoke your flow and the debugger should automatically break at your debugger
statement.
To debug unit-tests, the process is much the same as debugging runtime, except that the command to execute is different. In your plugin directory, execute:
npm test -- --inspect-brk
There is also an API that can be used to programmatically create flow-nodes. The interface can be found in docs/API.md
.
sdk.load(file, action)
now performs schema validation against the contents of file
.name
, icon
, category
, and description
are now required properties. A flow-node must be specified in the YAML specification.name
, description
, are now required properties. A flow-node must have at least one method.outputs
or returns
and throws
, but cannot have output
with either returns
or throws
.name
, description
, and required
are now required properties.setContext()
method has been removed. To set the pluginContext
when loading flow-nodes, specify it as pluginContext
in the third argument of sdk.load()
(options
),. When defining actions using action()
, options
is provided as the second argument..parameter(id, schema, options)
no longer allows a boolean value as the third argument for setting the value required
. required
should instead be provided in the options
object as the third argument.MockRuntime
action result
from invoking a method no longer contains args
or context
properties. Instead of result.args[1]
the action response can be accessed from result.value
.error
output defined on the flow-node, or by calling an output callback with an error as the first argument outputs(error)
), the MockRuntime
action now throws the error instead of returning it in the result.MockRuntime
to ensure the arguments parameters
and authorizations
are passed as objects.returns
and throws
as an improvement over using outputs
. However, outputs
property is still available, but it cannot be used if using returns
and throws
.MockRuntime
action will now throw an error if provided with parameters which aren't defined on the method.authorizations
in YAML, or defined using .authorization()
. Now, Authorization parameters are included under the key parameters
in YAML, or defined using parameter()
and must be part of the Authorization
group.parameters
and authorizations
can no longer have the same key.params
. Previously, you would access parameters as req.params.paramName
and authorization parameters as req.authorizations.authName
. Now, you can access them directly through params
- e.g params.paramName
and params.authName
.outputs
has been removed from the action interface. throw error;
and return value;
should be used instead to trigger the error
or next
outputs. If next
is not defined, the default
or first non-error output will be triggered instead. To invoke custom outputs, return options.setOutput('custom', value)
should be used.next
.pluginContext
value to be shared between actions and getPlugin
. This is set by calling sdk.setContext(pluginContext)
, and accessed in actions from options.pluginContext
.MockRuntime
interface for testing your flow-nodes and their methods. A plugin.getFlowNodeIds()
method was added that returns the IDs of each flow-node within the plugin. Moreover, you can now get the names of all the available methods in a given flow-node with flownode.getMethods()
.SDK.clear
API.action
arguments to make the SDK more permissive.pluginConfig
: new SDK({ pluginConfig })
.pluginConfig
property was added to action options
. This is the same object as the pluginConfig
option provided to the SDK constructor.MockRuntime
interface for loading the plugin. Instead of calling getPlugin
directly, a loadPlugin
method was added to MockRuntime
that calls getPlugin
for you. Using this method, you can also pass plugin configuration and runtime options
(e.g. logger) into your tests, e.g. await MockRuntime.loadPlugin(getPlugin, pluginConfig, options)
, which resolves to plugin
.MockRuntime.validate
moved to plugin.validate
.MockRuntime.getFlowNode
moved to plugin.getFlowNode
.appDir
property was added to getPlugin options
, which is the API Builder's runtime project directory. When run in unit-tests, it is process.cwd
but you can override this in MockRuntime.loadPlugin
.logger
property was added to getPlugin options
and action options
, which is the API Builder's runtime logger. When run in unit-tests, it is stubbed to not do any logging, but you can override this in MockRuntime.loadPlugin
.MockRuntime
.description
if unset.axway-flow-sdk
to @axway/api-builder-sdk
@axway/api-builder
CLImocknode
and validate
from axway-flow-sdk
MockRuntime
with mock and validate
functionsMockRuntime
selector
. Now they will consider the type provided using initialType
as an option:.parameter('myToggle', {
type: 'boolean'
}, {
initialType: 'boolean'
})
false
as a third argument to .parameter()
, an object can be provided as { required: false }
.axway-flow -n
command would throw an errortest
directory.dot
dependency with ejs
when generating new flow-node plugins.This code is proprietary, closed source software licensed to you by Axway. All Rights Reserved. You may not modify Axway’s code without express written permission of Axway. You are licensed to use and distribute your services developed with the use of this software and dependencies, including distributing reasonable and appropriate portions of the Axway code and dependencies. Except as set forth above, this code MUST not be copied or otherwise redistributed without express written permission of Axway. This module is licensed as part of the Axway Platform and governed under the terms of the Axway license agreement (General Conditions) located here: https://support.axway.com/en/auth/general-conditions; EXCEPT THAT IF YOU RECEIVED A FREE SUBSCRIPTION, LICENSE, OR SUPPORT SUBSCRIPTION FOR THIS CODE, NOTWITHSTANDING THE LANGUAGE OF THE GENERAL CONDITIONS, AXWAY HEREBY DISCLAIMS ALL SUPPORT AND MAINTENANCE OBLIGATIONS, AS WELL AS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO IMPLIED INFRINGEMENT WARRANTIES, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, AND YOU ACCEPT THE PRODUCT AS-IS AND WITH ALL FAULTS, SOLELY AT YOUR OWN RISK. Your right to use this software is strictly limited to the term (if any) of the license or subscription originally granted to you.
FAQs
SDK for implementing custom plugins for API Builder
We found that @axway/api-builder-sdk demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 15 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncovered a malicious PyPI package exploiting Deezer’s API to enable coordinated music piracy through API abuse and C2 server control.
Research
The Socket Research Team discovered a malicious npm package, '@ton-wallet/create', stealing cryptocurrency wallet keys from developers and users in the TON ecosystem.
Security News
Newly introduced telemetry in devenv 1.4 sparked a backlash over privacy concerns, leading to the removal of its AI-powered feature after strong community pushback.