Node.js SDK

The Node.js support in The Ops Platform SDK allows you to write Ops in either JavaScript or Typescript. When you run ops init from the command-line, a JavaScript project will be created for you. To switch to TypeScript, you can copy the default ops.yml and Dockerfile from the JavaScript project and add them to your TypeScript project.

Node SDK Installation

You can install and use the SDK in a Node.js project like this:

$ npm install @cto.ai/sdk

Usage:

const { sdk, ux } from '@cto.ai/sdk';

sdk.exec

sdk.exec(command: string): Promise<{ stdout: string, stderr: string }>

Runs a shell command inside the container asynchronously. Returns the stdout and stderr output of the process.

Example:

Executing the following code in the command template:

import { sdk } from '@cto.ai/sdk'

const main = async () => {
    await sdk.exec('mkdir test-directory')
    const { stdout, stderr } = await sdk.exec('ls')

    sdk.log('stdout is:\\n', stdout)
    sdk.log('stderr is:\\n', stderr)
}

main()

will create a folder named test-directory in the container, and logs the following text.

stdout is:
demo.js
index.js
node_modules
package-lock.json
package.json
test-directory

stderr is:

sdk.getHostOS

sdk.getHostOS(): string

Returns the Operating System the host is running on. For remote ops, will return "unknown" as no host is accessible in the remote environment.

Example:

import { sdk } from '@cto.ai/sdk'

const main = async () => {
    const hostOs = sdk.getHostOS()

    sdk.log("Host's os is:", hostOs)
}

Output:

Host's os is: darwin

sdk.homeDir

sdk.homeDir(): string

Returns the home directory of the host machine.

Example:

import { sdk } from '@cto.ai/sdk'

const main = async () => {
  const homeDir = sdk.homeDir()

  console.log("Host's home directory is:", homeDir)
}

Output:

Host's home directory is: /root

sdk.log

sdk.log(...args: any[]): void

Logs to the console in in a standardized way. Will not be relayed to
the user in a remote environment (use ux.print for that).

Example:

import { sdk } from '@cto.ai/sdk'

const main = async () => {
  sdk.log('I am a log!', '\\nI am too!')
}

Output:

I am a log!
I am too!

sdk.getStatePath

sdk.getStatePath(): string

Returns the path of the state directory. The contents of this directory are persistent through a workflow, including on remote.

Example:

import { sdk } from '@cto.ai/sdk'

const main = async () => {
  const statePath = sdk.getStatePath()

  sdk.log('The state path is:', statePath)
}

Output:

The state path is: /root/.config/@cto.ai/ops/superman/test-op/00000000-1111-2222-3333-444444444444

sdk.setConfig

sdk.setConfig(key: string, value: string): Promise<void>

Stores a key-value pair in the persistent team configuration. If the key is already present, the value will be replaced with the one provided.

Example:

import { sdk } from '@cto.ai/sdk'

const main = async () => {
    const key = 'test-key'

    // config = {}
    const initialConfig = await sdk.getConfig(key)
    sdk.log('Initial config', initialConfig)

    // config = { test-key: 'Value one' }
    await sdk.setConfig(key, 'Value one')
    const insertedConfig = await sdk.getConfig(key)
    sdk.log('Inserted config', insertedConfig)

    // config = { test-key: 'Value two' }
    await sdk.setConfig(key, 'Value two')
    const updatedConfig = await sdk.getConfig(key)
    sdk.log('Updated config', updatedConfig)
}

Output:

Initial config null
Inserted config Value one
Updated config Value two

sdk.getConfig

sdk.getConfig(key: string): Promise<string | null>

Gets the value that is saved under the given key in the persistent team configuration, or null if the key is not set.

Example

See sdk.setConfig above.

sdk.getAllConfig

sdk.getAllConfig(): Promise<object>

Gets the full contents of the persistent team configuration.

Example

import { sdk } from '@cto.ai/sdk'

const main = async () => {
    await sdk.setConfig('key1', 'Value one')
    await sdk.setConfig('key2', 'Value two')
    const fullConfig = await sdk.getAllConfig()
    sdk.log('Full config: ', JSON.stringify(fullConfig))
}

sdk.getSecret

sdk.getSecret(key: string): Promise<string>

Requests a secret from the secret store with the given key.

If the secret exists, it is returned, printing a notification to the user that it has been accessed.

Otherwise, the user is prompted to provide a replacement, either from the secret store or by direct entry through their interface.

Example

import { sdk } from '@cto.ai/sdk'

const run = async () => {
    const secret = sdk.getSecret('SECRET')
    // `ux.print` hides secret values but `sdk.log` does not.
    sdk.log(`my secret is ${secret}`)
}

run()

Output

my secret is SUPER_SECRET_VALUE

sdk.setSecret

sdk.setSecret(key: string, value: string): Promise<string | null>

Sets a particular value into the secret store.

If the secret already exists, the user is prompted on whether to overwrite it.

Returns the key that the secret is set to, or null if the user declines to overwrite the existing value.

Example

import { sdk, ux } from '@cto.ai/sdk'

const main = async () => {
    const key = await sdk.setSecret("secret1", "it's a secret to everybody")

    await ux.print(key)
}

Output

secret1

sdk.track

sdk.track(tags, metadata): Promise<any>

Send workflow events to The Ops Platform.

  • tags: (String || String[]) Tags for the event you want to track
  • metaData: (Object) Data you want to be tracked

sdk.events

Note: This feature is coming soon

sdk.events(team, filters): Promise<any>

Retrieve workflow events from The Ops Platform.

  • team: (String || String[]) The team you want to retrieve events for
  • filters: (Object) Filters for the events you want to retrieve