This extension provides a set of functions to make local development on the JourneyApps platform more efficient and convenient for the user.
Support
Note that this tool is not officially supported by JourneyApps. This tool is provided from the JourneyApps Dev community and is maintained by developers who use the JourneyApps platform on a daily basis.
This tool has the potential to affect production data if used on a production DB. The developers of this extension take no responsibility for any data corruption or issues that may arise from this extension.
Features
- Script/CloudCode task execution from the VSCode editor.
- VSCode debugging to be used on scripts.
- Quick project creation and configuration
- Script template creation
- REPL invocation into a deployment database
- Data migration between project deployments
- Data-model intellisense mapping and TypeScript support
Scripting basics
A script is a routine which is executed to modify or inspect data on a database. Scripts are essentially modules which have access to a globally initialized DB object. Every script must export a run
function which will be executed once the DB has been initialized. Scripts run on the Local development process which is described in the JourneyApps docs
Installation
- Download the latest install package from the github
releases
folder. The file will have the extension .vsix
.
- Open the VS Code Extension panel
- Install the extension by selecting the downloaded package file
Requirements
The following are assumed to be installed and available on the host machine:
- NodeJs
- Git
- Yarn
- TypeScript
A local clone of a "project-scripts" directory. This directory must have the following file structure:
/project-scripts/
/projects/
| /project_name/
| | script.js
| | config.json
| /other_project/
| | config.json
| | rootScript.js
| | /project_sub_directory
| | | someScript.js
/templates/
| basic.js
| batch.js
The above directory store is a good practice for storing all your script code and DB authentication in project config.json
files. BE SURE TO .gitignore config.json
FILES!
Each project requires a config.json
file in order to store credentials for automatic DB initialization.
Project Scripts Repo init [if no repo present yet]
If you don't have a project-scripts repo/folder setup, one can be setup using the following commands
cd [to some working directory you choose]
mkdir -p project-scripts/projects/[some_project_name]
cd project-scripts
Open a VSCode window in the project-scripts
directory
code .
git init
Add the following to a .gitignore
file
node_modules/
config.json
Create a template directory and create at least one sample js file as shown in the readme below.
mkdir templates
touch templates/basic.js
Be sure to populate your project specific config.json
file to match the template shown below.
touch projects/[some_project_name]/config.json
Create a token for scripts in the backend data browser and add it to your config.json
file.
Configuration
By default, config files are not committed to git. Config files config.json
should have the following format
{
"testing": {
"baseUrl": "https://run-testing.journeyapps.com/api/v4/appid",
"token": "token"
},
"staging": {
"baseUrl": "https://run-staging.journeyapps.com/api/v4/appid",
"token": "token"
},
"production": {
"baseUrl": "https://run.journeyapps.com/api/v4/appid",
"token": "token"
}
}
Known Issues
Breakpoint configurations are shared between all projects.
Scripts should export a run
function which can accept optional arguments. Arguments are only passed if using the js-run-arguments
command.
async function run(args) {
}
module.exports = { run: run };
Executing a script
Open the script file: This will be either [script_name].js
or index.ts
Open the command pallet in VSCode
run Run As JourneyScript
for normal debugging
run Run As JourneyScript with arguments
to pass arguments to the script
The extension will import your active script, initialize a DB connection using the credentials selected and then execute your `run` function. Be sure to specify any breakpoints before executing your script.
Executing JavaScript
Executing TypeScript
TypeScript projects need to be able to execute yarn install
and a tsc
build command. These commands are executed via a shell interface. Make sure that yarn and tsc are available in your shell before proceeding. These can be installed via:
npm install -g yarn typescript
Creating a project
While having the project-scripts
repository open:
Right click on the projects
folder in the VS Code Explorer pane. Select Create JourneyScript project
from the context menu and follow the prompts.
Creating a script
While having the project-scripts
repository open:
Right click on either the project's folder or a sub folder in the project directory in the VS Code Explorer pane. Select Create new JourneyScript script
for Javascript or Create new JourneyScript TypeScript project
for TypeScript from the context menu. Select a template to use. Templates are stored in the project-scripts/templates/
directory.
JavaScript:
TypeScript:
TypeScript projects need to be able to execute yarn install
and a tsc
build command. These commands are executed via a shell interface. Make sure that yarn and tsc are available in your shell before proceeding. These can be installed via:
npm install -g yarn typescript
Invoke REPL in a deployment
While having the project-scripts
repository open:
Right click on either the project's folder or a sub folder in the project directory in the VS Code Explorer pane. Select Open JounreyScript REPL
from the context menu. Choose the deployment you would like to be loaded for the REPL session.
Note: async/await is not entirely supported. It can be used in async functions, but not on a line by line basis
From the Context menu:
Type `Open JourneyScript REPL` in order to open a REPL for a selected project. This functionality can be used having any folder (not necessarily the project-scripts folder) open in VSCode.
Migrating Data
NOTE: Migrating data makes backend API DB call and creates/updates objects. Be sure to disable webhooks before migration if necessary.
Data can be migrated between deployments of a project. Objects will be created using the Journey Backend API. This means all objects will have matching id
values after migration. A migration operation consists of put
operations which will add new objects or update existing objects in the destination DB.
While having the project-scripts
repository open:
Right click on either the project's folder or a sub folder in the project directory in the VS Code Explorer pane. Select Migrate JourneyDB Data
. Follow the prompts to select a source and destination deployment.
From the Context menu:
Type `Migrate JourneyDB Data` and select a project. This functionality can be used having any folder (not necessarily the project-scripts folder) open in VSCode.
When migrating master data and performing updates to existing data, a diff overview of what changes would occur is possible by selecting the diff option for a model. Single data migrations are possible while in the diff view.
Using types with JavaScript
The datamodel of an app enviroment can be mapped to a Typescript definition file. This file can be imported and used for intellisense in JS development.
Right click on the project's folder or the script project sub-folder. Select "Refresh JourneyScript Datamodel Definition". Select the app environment you would like to use to construct the data model mapping from. A _DB.d.ts
file will be created in the selected directory.
JS files potentially need to use the /// <reference path="./_DB.d.ts" />
line to include the definitions.
Adding //ts-check
to the file will impose stricter type checking, but it is not required to get suggestions.
Example code: (\templates\intellisense_batch.js)
//remove this for less stringent type checking
//@ts-check
//This is required if your active workspace folder contains multiple projects and DB datamodel definitions
/// <reference path="./_DB.d.ts" />
/**
* The core functionality of the script
* @param {Array<any>} args
*/
async function run(args) {
let batch = new DB.Batch();
return batch.execute();
}
module.exports = {
run: run
}
VS code interprets the available *.d.ts
files using the active workspace directory (The folder you opened). If you have opened the project folder and not the project-scripts folder then you should not need to include the /// <reference path="./_DB.d.ts" />
line. If you have multiple projects and multiple *.d.ts
present in your active directory, you might not get the expected results if you do not include the <reference path>
identifier.
Typescript
Typescript projects now mimic the Cloudcode TypeScript method of compilation.
Use the context menu of the project script folder directory to create new TypeScript scripts and to build and debug/run them.
Make sure you have yarn
and tsc
installed globally on your system.
Global use
Some functions of this extension are available while not working in the project-scripts
folder. The credentials for the projects in the project-scripts
folder can still be used elsewhere if the path is defined in your User level VSCode preferences.
Attempting to use global functions should inquire for the path. It can also be set by entering the Preferences: Open User Settings
command. Navigate to the JSRun setting and enter the path to the project-scripts
directory. Be sure to end the path with a /
.
CloudCode Emulation
There are many similarities between a script and a CloudCode task which is triggered as a test or from a webhook. The extension is able to trigger these tasks in a limited capacity using the Global use method described above.
cd [The CloudCode task folder]
npm install
Be sure to add a git ignore entry in the .gitignore
file of the app repo for the node_modules/
folder.
Once the dependencies are installed the index.js/index.ts file should be executable as a JourneyScript. The run function context will have this.env === 'testing'
, this.source === CloudCode.EDITOR_TEST
and the backend auth details will be present in this.backend
.
CloudCode global
The CloudCode namespace will also be available on the global
level. Some of the functionalities are limited. The CloudCode.scheduleTask
method can only accept a task of the same dirname (containing the index.js/ts) as the CC task being executed - ie only the same task can be scheduled. Only a after
parameter can be used for a delay, at
is not supported. The value passed in the parameters
field will be used as the argument for the next invocation of the run
function. The run function context will have this.source === CloudCode.ENQUEUE
.
TypeScript Tasks
The global CloudCode
namespace is not available by default. For local purposes it is required to be declared as a global variable.
npm install @journeyapps/cloudcode
import {CloudCode as CCloudCode} from '@journeyapps/cloudcode';
declare const CloudCode: typeof CCloudCode;
import / export
ESM modules are supported in CloudCode but are not supported locally. Replace import
calls with require
and export declarations with an equivalent module.exports =
statement
API Extensions
The following API modules are globally available to your scripts (There are currently no definitions for TypeScript, but they are available):
SessionsAPI
A wrapper for the Sessions API.
Hash
The Hash class allows quickly caching data for retrieval by an id or field. The constructor takes an Array as a parameter.
Syntax
new Hash(array, [field])
- array: obj[] - An array of objects to hash.
- field: string | function - [optional, defaults to
id
] The field you want to build the hash on. Can also be a function which takes an element of the array and returns a string.
let obj = object_data[related_object.object_id];
You can also hash on a related field other than an id:
let object_data = new Hash(await DB.object.all().toArray(), 'other_field');
let obj = object_data[other_field];
Or you can use a function to return a string:
let object_data = new Hash(await DB.object.all().toArray(), obj => `${obj.relationship_id}${obj.another_relationship_id}`);
let obj = object_data[`${related_object.relationship_id}${related_object.another_relationship_id}`];