src/
Describes the src/
folder for applications in Optimizely Connect Platform (OCP).
The src/
directory contains source code for your app and is where you will spend most of your time developing your app. You can organize your code however you prefer, but some folders have a specific purpose in Optimizely Connect Platform (OCP):
src/lifecycle/
– Contains theLifecycle.ts
file, which contains callback methods OCP calls at various points in the app's lifecycle.src/functions/
– Contains the code for functions.src/jobs/
– Contains the code for jobs.src/schema/
– Contains YAML files with declarative data schema definitions.
You can add any other directory and reference files from there in your code. A common practice is to create a src/lib/
directory for your own libraries and utilities.
lifecycle/
folder
lifecycle/
folderDefine functions that you call throughout the lifecycle of an app in the lifecycle/
folder.
Lifecycle resources:
Note
There is no
lifecycle
section in theapp.yml
file. OCP reads thelifecycle/Lifecycle.ts
file directly and executes methods from it.
lifecycle/
functions
lifecycle/
functionsFunction | Called | Parameters | Return |
---|---|---|---|
onSettingsForm | on settings form action | page, action, formData | App.Response() |
onUpgrade | on version upgrade | fromVersion | {success: } |
onFinalizeUpgrade | after onUpgrade | fromVersion | {success: } |
onInstall | on user install of app | none | {success: } |
onUninstall | on user uninstall of app | none | {success: } |
Example Lifecycle.ts
file
Lifecycle.ts
fileimport * as App from '@zaius/app-sdk';
import {logger, storage} from '@zaius/app-sdk';
export class Lifecycle extends App.Lifecycle {
public async onInstall(): Promise<App.LifecycleResult> {
try {
logger.info(`Performing Install`);
// TODO: any operation you need to perform during installation
return {success: true};
} catch (error) {
logger.error('Error during installation:', error);
return {success: false, retryable: true};
}
}
public async onSetingsForm(page: string, action: string, formData: App.ValueHash): Promise<App.Response> {
try {
// TODO: any logic you need to perform when a setup form section is submitted
// When you are finished, save the form data to the settings store
storage.settings.put(page, formData);
return new App.Response(200);
} catch (e) {
return new App.Response(500);
}
}
public async onUpgrade(fromVersion: string): Promise<App.LifecycleResult> {
// TODO: any logic required when upgrading from a previous version of the app
// Note: `fromVersion` may not be the most recent version or could be a beta version
return {success: true};
}
public async onFinalizeUpgrade(fromVersion: string): Promise<App.LifecycleResult> {
// TODO: any logic required when finalizing an upgrade from a previous version
// At this point, new webhook URLs have been created for any new functions in this version
return {success: true};
}
public async onUninstall(): Promise<App.LifecycleResult> {
// TODO: any logic required to properly uninstall the app
return {success: true};
}
}
functions/
folder
functions/
folderFunctions are small, executable blocks of code typically triggered from a real-time event. An app can have any number of functions stored in the src/functions
directory.
Functions resources:
Below is an example of the functions
section in the app.yml
file:
functions:
get_esp_lists: #<-- name used for form sources and reference within the app
entry_point: GetEspLists #<-- File and Class name
description: Pulls the lists from the ESP to select which ones you want imported
functions/
functions
functions/
functionsFunction | Called | Parameters | Return |
---|---|---|---|
perform | on request | Request | App.Response() |
Example GetEspLists.ts
file
GetEspLists.ts
fileimport * as App from '@zaius/app-sdk';
import {logger} from '@zaius/app-sdk';
import {z} from '@zaius/node-sdk';
/**
* Returns the lists within ODP
*/
export class GetEspLists extends App.Function {
public async perform(): Promise<App.Response> {
try {
return new App.Response(200, await z.lists.getLists().data);
} catch (e) {
logger.error(e);
return new App.Response(500, `An unexpected error occurred: ${e}`);
}
}
}
}
jobs/
folder
jobs/
folderJobs are asynchronous functions with an undefined completion time. Jobs are typically used for historical imports of data or recurring imports of data from APIs that do not support real-time functions.
Jobs resources:
Below is an example of the jobs
section in the app.yml
file:
jobs:
historical_import: #<-- used to reference within app
entry_point: Import #<-- File/Class name
description: Performs a one-time historical import when triggered
jobs/
functions
jobs/
functionsFunction | Called | Parameters | Return |
---|---|---|---|
prepare | before perform | params, status | status |
perform | after perform, until status.complete == true | status | status |
Note
status
is an interface that contains the information needed to complete a unit of work. Often, this includes the last page called from an API, number of records imported, and so on.
Example Import.ts
file
Import.ts
fileimport * as App from '@zaius/app-sdk';
import {logger, ValueHash} from '@zaius/app-sdk';
interface ImportJobStatus extends App.JobStatus {
state: {
// TODO: define your job state here
};
}
/**
* Performs an import
*/
export class Import extends App.Job {
/**
* Prepares to run a job. Prepare is called at the start of a job
* and again only if the job was interrupted and is being resumed.
* Use this function to read secrets and establish connections to simplify the job loop (perform).
* @param params a hash if params were supplied to the job run, otherwise an empty hash
* @param status if job was interrupted and should continue from the last known state
*/
public async prepare(params: ValueHash, status?: ImportJobStatus): Promise<ImportJobStatus> {
logger.info('Preparing Import Job with params:', params, 'and status', status);
// TODO: Prepare for a job run
return {state: {}, complete: false};
}
/**
* Performs a unit of work. Jobs should perform a small unit of work and then return the current state.
* Perform is called in a loop where the previously returned state will be given to the next iteration.
* Iteration will continue until the returned state.complete is set to true or the job is interrupted.
* @param status last known job state and status
* @returns The current JobStatus/state that you can use to perform the next iteration or resume a job if interrupted.
*/
public async perform(status: ImportJobStatus): Promise<ImportJobStatus> {
// TODO: perform a small unit of work, then return your state
// When you are finished, set complete to true
status.complete = true;
// Return your status. If complete is false, perform will be called again imediately with the status you returned
return status;
}
}
schema/
folder
schema/
folderThe src/schema
folder contains YAML files with declarative, static schema definitions for an app. OCP reads these files when users install or upgrade an app and makes sure the OCP account where the app is installed contains all declared objects and fields.
For more information about schema, see Schema for objects and fields.
Updated 16 days ago