You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -13,7 +13,9 @@ of key patterns in the OpenFn ecosystem which it is important to learn.
13
13
14
14
:::tip
15
15
16
-
If you're writing jobs on the platform app (Lightning), you can use the [AI Assistant](/documentation/build/ai-assistant) to help you. You'll find it in the Inspector.
16
+
If you're writing jobs on the platform app (Lightning), you can use the
17
+
[AI Assistant](/documentation/build/ai-assistant) to help you. You'll find it in
18
+
the Inspector.
17
19
18
20
:::
19
21
@@ -915,6 +917,111 @@ fn(state => {
915
917
});
916
918
```
917
919
920
+
## Globals
921
+
922
+
:::warning Availability
923
+
924
+
Globals are new to CLI version X.X.X and not yet available in Lightning
925
+
926
+
:::
927
+
928
+
Each step in your workflow runs in isolation: state is the only way to share
929
+
information between steps.
930
+
931
+
Since CLI vX.X.X, you can declare global variables and functions which can be
932
+
re-used throughout all steps in your workflow. This is particularly useful for
933
+
declaring re-usable functions.
934
+
935
+
Globals are defined in a special kind of step. Everything you export from this
936
+
"step" will be made globally available to all other steps.
937
+
938
+
For example, your globals may look like this:
939
+
940
+
```js
941
+
exportconstPROJECT_ID='1245';
942
+
943
+
exportfunctiontoKebabCase(str) {
944
+
returnstr.replace(/\s/g, '-');
945
+
}
946
+
```
947
+
948
+
This exports a constant, `PROJECT_ID`, and a (rather naive) helper function to
949
+
convert any string into kebab-case.
950
+
951
+
In the CLI, you might save these to a file called `globals.js`, and reference
952
+
them in `workflow.json` as a sibling of `steps`:
953
+
954
+
```json
955
+
{
956
+
"workflow": {
957
+
"globals": "./globals.js",
958
+
"steps": [{...}, {...} ]
959
+
}
960
+
}
961
+
```
962
+
963
+
You can now reference these in any job code:
964
+
965
+
```js
966
+
fn(state=> {
967
+
state.id=toKebabCase(state.data.name);
968
+
return state;
969
+
});
970
+
```
971
+
972
+
There are some important rules to bear in mind when using globals:
973
+
974
+
- You cannot import other modules inside globals. Globals are not a replacement
975
+
for adaptors.
976
+
- Exported functions are not operations, and cannot be used at the top-level of
977
+
a job expression (unless you specifically write it that way, see below)
978
+
- The contents of globals are immutable: you cannot change their values and they
979
+
are reset in-between steps. You can of course pass state into a global
980
+
function and mutate it.
981
+
982
+
:::info Global functions are not Operations
983
+
984
+
A really important (but quite complicated) rule of globals is that any function
985
+
you export is not necessarily an Operation.
986
+
987
+
An Operation is a function that returns a function that takes state and returns
988
+
state. Operations are provided by adaptor functions and can only be used at the
989
+
top level of your code.
990
+
991
+
But a function exported from globals is just a function. If you try and use it a
992
+
the top level of job, you'll get an error like
993
+
`TypeError: fn is not a function`.
994
+
995
+
For example:
996
+
997
+
```js
998
+
fn(state=> {
999
+
// a valid fn block
1000
+
return state;
1001
+
});
1002
+
toKebabCase(state.name); // TypeError: fn is not a function!
1003
+
```
1004
+
1005
+
You can define your own operations by structuring your global functions
1006
+
correctly. Remember that your function must return a function, and that this
1007
+
inner function must take and return state. Your operation will probably want to
1008
+
write to state too (by convention we write to state.data but you can do whatever
1009
+
you like).
1010
+
1011
+
An operation variation of `toKebabCase` might look like this:
1012
+
1013
+
```js
1014
+
// globals.js
1015
+
exportfunctiontoKebabCase(str) {
1016
+
returnstate=> {
1017
+
state.result=str.replace(/\s/g, '-');
1018
+
return state;
1019
+
};
1020
+
}
1021
+
```
1022
+
1023
+
:::
1024
+
918
1025
## Using Cursors
919
1026
920
1027
Sometimes it is useful to maintain a rolling cursor position on the backend
@@ -1159,27 +1266,30 @@ fn(state => {
1159
1266
1160
1267
## Referencing credential secrets in your job code
1161
1268
1162
-
If you want to reference any credential secrets in your job code, you can still map keys from your `state.configuration`. See example below that will dynamically map the username and password from your `configuration` (or "credential" if using the app) into your http request body.
1269
+
If you want to reference any credential secrets in your job code, you can still
1270
+
map keys from your `state.configuration`. See example below that will
1271
+
dynamically map the username and password from your `configuration` (or
1272
+
"credential" if using the app) into your http request body.
1163
1273
1164
1274
```js
1165
1275
post('/api/v1/auth/login', {
1166
-
body: {
1276
+
body: {
1167
1277
username:$.configuration.username, //map the UN from credential
1168
-
password:$.configuration.password//map the PW from credential
1169
-
},
1170
-
headers: {'content-type':'application/json'},
1171
-
})
1278
+
password:$.configuration.password,//map the PW from credential
1279
+
},
1280
+
headers: {'content-type':'application/json'},
1281
+
});
1172
1282
```
1173
1283
1174
1284
:::info OpenFn scrubs Configuration & Functions from final state
1175
1285
1176
1286
OpenFn will automatically scrub the `configuration` key and any functions from
1177
-
your final state, as well as from logs if running workflows on the app. This is to help ensure that your credential secrets are kept secure and won't be leaked into History.
1287
+
your final state, as well as from logs if running workflows on the app. This is
1288
+
to help ensure that your credential secrets are kept secure and won't be leaked
1289
+
into History.
1178
1290
1179
1291
:::
1180
1292
1181
-
1182
-
1183
1293
<!--
1184
1294
I would like to include this BUT fields is not an operation and so works a bit differently
0 commit comments