epicenter-libs 3.33.0 → 3.34.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/browser/epicenter.js +105 -2
- package/dist/browser/epicenter.js.map +1 -1
- package/dist/cjs/epicenter.js +105 -2
- package/dist/cjs/epicenter.js.map +1 -1
- package/dist/epicenter.js +105 -2
- package/dist/epicenter.js.map +1 -1
- package/dist/epicenter.min.js +1 -1
- package/dist/epicenter.min.js.map +1 -1
- package/dist/module/epicenter.js +105 -2
- package/dist/module/epicenter.js.map +1 -1
- package/dist/types/adapters/chat.d.ts +63 -0
- package/package.json +1 -1
- package/src/adapters/chat.ts +95 -0
- package/src/utils/identification.ts +4 -0
- package/dist/test/_virtual/runtime.js +0 -3
- package/dist/test/_virtual/runtime2.js +0 -3
- package/dist/test/adapters/account.js +0 -169
- package/dist/test/adapters/admin.js +0 -53
- package/dist/test/adapters/asset.js +0 -425
- package/dist/test/adapters/authentication.js +0 -349
- package/dist/test/adapters/channel.js +0 -201
- package/dist/test/adapters/chat.js +0 -199
- package/dist/test/adapters/cometd.js +0 -514
- package/dist/test/adapters/consensus.js +0 -484
- package/dist/test/adapters/daily.js +0 -244
- package/dist/test/adapters/email.js +0 -179
- package/dist/test/adapters/episode.js +0 -175
- package/dist/test/adapters/group.js +0 -655
- package/dist/test/adapters/leaderboard.js +0 -162
- package/dist/test/adapters/matchmaker.js +0 -159
- package/dist/test/adapters/presence.js +0 -85
- package/dist/test/adapters/project.js +0 -94
- package/dist/test/adapters/recaptcha.js +0 -24
- package/dist/test/adapters/run.js +0 -1008
- package/dist/test/adapters/somebody.js +0 -154
- package/dist/test/adapters/task.js +0 -192
- package/dist/test/adapters/time.js +0 -28
- package/dist/test/adapters/user.js +0 -105
- package/dist/test/adapters/vault.js +0 -403
- package/dist/test/adapters/video.js +0 -249
- package/dist/test/adapters/vonage.js +0 -130
- package/dist/test/adapters/wallet.js +0 -130
- package/dist/test/adapters/world.js +0 -507
- package/dist/test/apis/video.js +0 -294
- package/dist/test/apis/vonage.js +0 -121
- package/dist/test/epicenter.js +0 -121
- package/dist/test/node_modules/@babel/runtime/helpers/esm/defineProperty.js +0 -12
- package/dist/test/node_modules/@babel/runtime/helpers/esm/toPrimitive.js +0 -14
- package/dist/test/node_modules/@babel/runtime/helpers/esm/toPropertyKey.js +0 -9
- package/dist/test/node_modules/@babel/runtime/helpers/esm/typeof.js +0 -11
- package/dist/test/node_modules/cometd/AckExtension.js +0 -91
- package/dist/test/node_modules/cometd/CallbackPollingTransport.js +0 -148
- package/dist/test/node_modules/cometd/Client.js +0 -2160
- package/dist/test/node_modules/cometd/Extension.js +0 -47
- package/dist/test/node_modules/cometd/LongPollingTransport.js +0 -135
- package/dist/test/node_modules/cometd/ReloadExtension.js +0 -214
- package/dist/test/node_modules/cometd/RequestTransport.js +0 -252
- package/dist/test/node_modules/cometd/Transport.js +0 -167
- package/dist/test/node_modules/cometd/TransportRegistry.js +0 -107
- package/dist/test/node_modules/cometd/WebSocketTransport.js +0 -384
- package/dist/test/node_modules/cometd/cometd.js +0 -9
- package/dist/test/node_modules/regenerator-runtime/runtime.js +0 -773
- package/dist/test/utilities.js +0 -17
- package/dist/test/utils/config.js +0 -189
- package/dist/test/utils/constants.js +0 -293
- package/dist/test/utils/cookies.js +0 -75
- package/dist/test/utils/error-manager.js +0 -57
- package/dist/test/utils/error.js +0 -12
- package/dist/test/utils/fault.js +0 -34
- package/dist/test/utils/filter-parser.js +0 -68
- package/dist/test/utils/helpers.js +0 -9
- package/dist/test/utils/identification.js +0 -161
- package/dist/test/utils/result.js +0 -20
- package/dist/test/utils/router.js +0 -551
- package/dist/test/utils/store.js +0 -79
|
@@ -1,1008 +0,0 @@
|
|
|
1
|
-
import { SCOPE_BOUNDARY, RITUAL } from '../utils/constants.js';
|
|
2
|
-
import '../utils/helpers.js';
|
|
3
|
-
import { parseFilterInput } from '../utils/filter-parser.js';
|
|
4
|
-
import EpicenterError from '../utils/error.js';
|
|
5
|
-
import '../utils/config.js';
|
|
6
|
-
import identification from '../utils/identification.js';
|
|
7
|
-
import '../utils/error-manager.js';
|
|
8
|
-
import Router from '../utils/router.js';
|
|
9
|
-
|
|
10
|
-
let MORPHOLOGY = /*#__PURE__*/function (MORPHOLOGY) {
|
|
11
|
-
MORPHOLOGY["MANY"] = "MANY";
|
|
12
|
-
MORPHOLOGY["PROXY"] = "PROXY";
|
|
13
|
-
MORPHOLOGY["SINGULAR"] = "SINGULAR";
|
|
14
|
-
return MORPHOLOGY;
|
|
15
|
-
}({});
|
|
16
|
-
/**
|
|
17
|
-
* Creates a run. By default, all runs are created with the user's ID (`userKey`), except in the case of world-scoped runs.
|
|
18
|
-
* If no permit is specified, platform will assign a default determined by the session user type and the scope boundary.
|
|
19
|
-
* For a participant creating a run, the default readLock/writeLock is `USER/USER`, unless that run is scoped to a world,
|
|
20
|
-
* in which case `PARTICIPANT/FACILITATOR` is the default. Admins and facilitators/reviewers have their own defaults.
|
|
21
|
-
* Base URL: POST `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run`
|
|
22
|
-
*
|
|
23
|
-
* @example
|
|
24
|
-
* import { runAdapter, SCOPE_BOUNDARY } from 'epicenter-libs';
|
|
25
|
-
* await runAdapter.create('model.py', {
|
|
26
|
-
* scopeBoundary: SCOPE_BOUNDARY.GROUP,
|
|
27
|
-
* scopeKey: '0000017dd3bf540e5ada5b1e058f08f20461'
|
|
28
|
-
* });
|
|
29
|
-
*
|
|
30
|
-
* @param model Name of your model file
|
|
31
|
-
* @param scope Scope associated with your run
|
|
32
|
-
* @param scope.scopeBoundary Scope boundary, defines the type of scope; See [scope boundary](#SCOPE_BOUNDARY) for all types
|
|
33
|
-
* @param scope.scopeKey Scope key, a unique identifier tied to the scope. E.g., if your `scopeBoundary` is `GROUP`, your `scopeKey` will be your `groupKey`; for `EPISODE`, `episodeKey`, etc.
|
|
34
|
-
* @param [optionals] Optional arguments; pass network call options overrides here. Special arguments specific to this method are listed below if they exist.
|
|
35
|
-
* @param [optionals.readLock] Read permission role; one of the strings defined in ROLE
|
|
36
|
-
* @param [optionals.writeLock] Write permission role; one of the strings defined in ROLE
|
|
37
|
-
* @param [optionals.ephemeral] Used for testing. If true, the run will only exist so long as its in memory; makes it so that nothing is written to the database, history, or variables.
|
|
38
|
-
* @param [optionals.trackingKey] Tracking key
|
|
39
|
-
* @param [optionals.modelContext] .ctx2 file overrides, this is not tracked by clone operations
|
|
40
|
-
* @param [optionals.executionContext] Carries arguments for model file worker on model initialization. This is tracked by clone operations.
|
|
41
|
-
* @param [optionals.allowChannel] Opt into push notifications for this resource. Applicable to projects with phylogeny >= SILENT
|
|
42
|
-
* @returns promise that resolves to the newly created run
|
|
43
|
-
*/
|
|
44
|
-
async function create(model, scope, optionals = {}) {
|
|
45
|
-
const {
|
|
46
|
-
scopeBoundary,
|
|
47
|
-
scopeKey,
|
|
48
|
-
userKey
|
|
49
|
-
} = scope;
|
|
50
|
-
const {
|
|
51
|
-
readLock,
|
|
52
|
-
writeLock,
|
|
53
|
-
ephemeral,
|
|
54
|
-
trackingKey,
|
|
55
|
-
modelContext,
|
|
56
|
-
executionContext,
|
|
57
|
-
allowChannel,
|
|
58
|
-
...routingOptions
|
|
59
|
-
} = optionals;
|
|
60
|
-
const {
|
|
61
|
-
WORLD
|
|
62
|
-
} = SCOPE_BOUNDARY;
|
|
63
|
-
const session = identification.session;
|
|
64
|
-
const hasPermit = readLock || writeLock;
|
|
65
|
-
const headers = Object.assign({}, routingOptions.headers, hasPermit ? {
|
|
66
|
-
'X-Forio-Confirmation': true
|
|
67
|
-
} : {});
|
|
68
|
-
const permit = hasPermit ? {
|
|
69
|
-
readLock,
|
|
70
|
-
writeLock
|
|
71
|
-
} : undefined;
|
|
72
|
-
return await new Router().post('/run', {
|
|
73
|
-
body: {
|
|
74
|
-
scope: {
|
|
75
|
-
scopeBoundary,
|
|
76
|
-
scopeKey,
|
|
77
|
-
userKey: scopeBoundary === WORLD ? undefined : userKey !== null && userKey !== void 0 ? userKey : session === null || session === void 0 ? void 0 : session.userKey
|
|
78
|
-
},
|
|
79
|
-
permit,
|
|
80
|
-
morphology: 'MANY',
|
|
81
|
-
trackingKey,
|
|
82
|
-
modelFile: model,
|
|
83
|
-
modelContext: modelContext || {/* Is not recorded for clone. Overrides model ctx2 file. */},
|
|
84
|
-
executionContext: executionContext || {/* Affected by clone. Carries arguments for model file worker on model initialization */},
|
|
85
|
-
ephemeral,
|
|
86
|
-
allowChannel
|
|
87
|
-
},
|
|
88
|
-
...routingOptions,
|
|
89
|
-
headers
|
|
90
|
-
}).then(({
|
|
91
|
-
body
|
|
92
|
-
}) => body);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Creates a project scoped run
|
|
97
|
-
* Base URL: POST `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/singular`
|
|
98
|
-
*
|
|
99
|
-
* @example
|
|
100
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
101
|
-
* await runAdapter.createSingular('model.py');
|
|
102
|
-
*
|
|
103
|
-
* @param model Name of your model file
|
|
104
|
-
* @param [optionals] Optional arguments; pass network call options overrides here. Special arguments specific to this method are listed below if they exist.
|
|
105
|
-
* @param [optionals.readLock] Read permission role; one of the strings defined in ROLE
|
|
106
|
-
* @param [optionals.writeLock] Write permission role; one of the strings defined in ROLE
|
|
107
|
-
* @param [optionals.ephemeral] Used for testing. If true, the run will only exist so long as its in memory; makes it so that nothing is written to the database, history, or variables.
|
|
108
|
-
* @param [optionals.modelContext] .ctx2 file overrides, this is not tracked by clone operations
|
|
109
|
-
* @param [optionals.executionContext] Carries arguments for model file worker on model initialization. This is tracked by clone operations.
|
|
110
|
-
* @returns promise that resolves to the newly created run
|
|
111
|
-
*/
|
|
112
|
-
async function createSingular(model, optionals = {}) {
|
|
113
|
-
const {
|
|
114
|
-
readLock,
|
|
115
|
-
writeLock,
|
|
116
|
-
ephemeral,
|
|
117
|
-
modelContext,
|
|
118
|
-
executionContext,
|
|
119
|
-
...routingOptions
|
|
120
|
-
} = optionals;
|
|
121
|
-
const hasPermit = readLock || writeLock;
|
|
122
|
-
const headers = Object.assign({}, routingOptions.headers, hasPermit ? {
|
|
123
|
-
'X-Forio-Confirmation': true
|
|
124
|
-
} : {});
|
|
125
|
-
const permit = hasPermit ? {
|
|
126
|
-
readLock,
|
|
127
|
-
writeLock
|
|
128
|
-
} : undefined;
|
|
129
|
-
return await new Router().post('/run/singular', {
|
|
130
|
-
body: {
|
|
131
|
-
modelFile: model,
|
|
132
|
-
permit,
|
|
133
|
-
modelContext: modelContext || {/* Is not recorded for clone. Overrides model ctx2 file. */},
|
|
134
|
-
executionContext: executionContext || {/* Affected by clone. Carries arguments for model file worker on model initialization */},
|
|
135
|
-
ephemeral
|
|
136
|
-
},
|
|
137
|
-
...routingOptions,
|
|
138
|
-
headers
|
|
139
|
-
}).then(({
|
|
140
|
-
body
|
|
141
|
-
}) => body);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Gets the singular run's runKey
|
|
146
|
-
* Base URL: GET `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/singular/key`
|
|
147
|
-
*
|
|
148
|
-
* @example
|
|
149
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
150
|
-
* const runKey = await runAdapter.getSingularRunKey();
|
|
151
|
-
*
|
|
152
|
-
* @param [optionals] Optional arguments; pass network call options overrides here.
|
|
153
|
-
* @returns promise that resolves to a runKey
|
|
154
|
-
*/
|
|
155
|
-
async function getSingularRunKey(optionals = {}) {
|
|
156
|
-
return await new Router().get('/run/singular/key', optionals).then(({
|
|
157
|
-
body
|
|
158
|
-
}) => body);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Clone a run
|
|
163
|
-
* Base URL: POST `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/clone/{RUN_KEY}`
|
|
164
|
-
*
|
|
165
|
-
* @example
|
|
166
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
167
|
-
* const clonedRun = await runAdapter.clone('00000173078afb05b4ae4c726637167a1a9e');
|
|
168
|
-
*
|
|
169
|
-
* @param runKey Run key for the run you want to clone
|
|
170
|
-
* @param [optionals] Optional arguments; pass network call options overrides here. Special arguments specific to this method are listed below if they exist.
|
|
171
|
-
* @param [optionals.ephemeral] Used for testing. If true, the run will only exist so long as its in memory; makes it so that nothing is written to the database, history, or variables.
|
|
172
|
-
* @param [optionals.trackingKey] Tracking key
|
|
173
|
-
* @param [optionals.modelContext] .ctx2 file overrides, this is not tracked by clone operations
|
|
174
|
-
* @param [optionals.executionContext] Carries arguments for model file worker on model initialization. This is tracked by clone operations.
|
|
175
|
-
* @returns promise that resolves to the cloned run
|
|
176
|
-
*/
|
|
177
|
-
async function clone(runKey, optionals = {}) {
|
|
178
|
-
const {
|
|
179
|
-
ephemeral,
|
|
180
|
-
trackingKey,
|
|
181
|
-
modelContext = {},
|
|
182
|
-
executionContext = {},
|
|
183
|
-
...routingOptions
|
|
184
|
-
} = optionals;
|
|
185
|
-
return await new Router().post(`/run/clone/${runKey}`, {
|
|
186
|
-
body: {
|
|
187
|
-
trackingKey,
|
|
188
|
-
modelContext,
|
|
189
|
-
executionContext,
|
|
190
|
-
ephemeral
|
|
191
|
-
},
|
|
192
|
-
...routingOptions
|
|
193
|
-
}).then(({
|
|
194
|
-
body
|
|
195
|
-
}) => body);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Restore a run into memory
|
|
200
|
-
* Base URL: POST `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/restore/{RUN_KEY}`
|
|
201
|
-
*
|
|
202
|
-
* @example
|
|
203
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
204
|
-
* const restoredRun = await runAdapter.restore('00000173078afb05b4ae4c726637167a1a9e');
|
|
205
|
-
*
|
|
206
|
-
* @param runKey Run key for the run you want to restore
|
|
207
|
-
* @param [optionals] Optional arguments; pass network call options overrides here. Special arguments specific to this method are listed below if they exist.
|
|
208
|
-
* @param [optionals.ephemeral] Used for testing. If true, the run will only exist so long as its in memory; makes it so that nothing is written to the database, history, or variables.
|
|
209
|
-
* @param [optionals.modelContext] .ctx2 file overrides, this is not tracked by clone operations
|
|
210
|
-
* @param [optionals.executionContext] Carries arguments for model file worker on model initialization. This is tracked by clone operations.
|
|
211
|
-
* @returns promise that resolves to the restored run
|
|
212
|
-
*/
|
|
213
|
-
async function restore(runKey, optionals = {}) {
|
|
214
|
-
const {
|
|
215
|
-
ephemeral,
|
|
216
|
-
modelContext = {},
|
|
217
|
-
executionContext = {},
|
|
218
|
-
...routingOptions
|
|
219
|
-
} = optionals;
|
|
220
|
-
return await new Router().post(`/run/restore/${runKey}`, {
|
|
221
|
-
body: {
|
|
222
|
-
modelContext,
|
|
223
|
-
executionContext,
|
|
224
|
-
ephemeral
|
|
225
|
-
},
|
|
226
|
-
...routingOptions
|
|
227
|
-
}).then(({
|
|
228
|
-
body
|
|
229
|
-
}) => body);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Rewind a run by a specified number of steps
|
|
234
|
-
* Base URL: POST `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/rewind/{RUN_KEY}`
|
|
235
|
-
*
|
|
236
|
-
* @example
|
|
237
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
238
|
-
* const rewoundRun = await runAdapter.rewind('00000173078afb05b4ae4c726637167a1a9e', 5);
|
|
239
|
-
*
|
|
240
|
-
* @param runKey Run key for the run you want to rewind
|
|
241
|
-
* @param steps Number of steps to rewind
|
|
242
|
-
* @param [optionals] Optional arguments; pass network call options overrides here. Special arguments specific to this method are listed below if they exist.
|
|
243
|
-
* @param [optionals.ephemeral] Used for testing. If true, the run will only exist so long as its in memory; makes it so that nothing is written to the database, history, or variables.
|
|
244
|
-
* @param [optionals.modelContext] .ctx2 file overrides, this is not tracked by clone operations
|
|
245
|
-
* @returns promise that resolves to the rewound run
|
|
246
|
-
*/
|
|
247
|
-
async function rewind(runKey, steps, optionals = {}) {
|
|
248
|
-
const {
|
|
249
|
-
ephemeral,
|
|
250
|
-
modelContext = {},
|
|
251
|
-
...routingOptions
|
|
252
|
-
} = optionals;
|
|
253
|
-
return await new Router().post(`/run/rewind/${runKey}`, {
|
|
254
|
-
body: {
|
|
255
|
-
rewindCount: steps,
|
|
256
|
-
modelContext,
|
|
257
|
-
ephemeral
|
|
258
|
-
},
|
|
259
|
-
...routingOptions
|
|
260
|
-
}).then(({
|
|
261
|
-
body
|
|
262
|
-
}) => body);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Updates a run's attributes
|
|
267
|
-
* Base URL: PATCH `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/{RUN_KEY}`
|
|
268
|
-
*
|
|
269
|
-
* @example
|
|
270
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
271
|
-
* const updatedRun = await runAdapter.update('00000173078afb05b4ae4c726637167a1a9e', {
|
|
272
|
-
* readLock: 'FACILITATOR',
|
|
273
|
-
* writeLock: 'FACILITATOR',
|
|
274
|
-
* marked: true,
|
|
275
|
-
* hidden: false,
|
|
276
|
-
* });
|
|
277
|
-
*
|
|
278
|
-
* @param runKey Key associated with the run
|
|
279
|
-
* @param update Object with the key-value pairs you would like to update
|
|
280
|
-
* @param update.readLock Read permission role; one of the strings defined in ROLE
|
|
281
|
-
* @param update.writeLock Write permission role; one of the strings defined in ROLE
|
|
282
|
-
* @param update.trackingKey Tracking key for the run
|
|
283
|
-
* @param update.marked Whether the run is marked (analogous to v2's 'saved')
|
|
284
|
-
* @param update.hidden Whether the run is hidden (analogous to v2's 'trashed')
|
|
285
|
-
* @param update.closed Closed is a flag that means do not restore, the run is done, no more play
|
|
286
|
-
* @param update.allowChannel Opt into push notifications for this resource. Applicable to projects with phylogeny >= SILENT
|
|
287
|
-
* @param [optionals] Optional arguments; pass network call options overrides here
|
|
288
|
-
* @returns promise that resolve to the updated run
|
|
289
|
-
*/
|
|
290
|
-
async function update(runKey, update, optionals = {}) {
|
|
291
|
-
const {
|
|
292
|
-
readLock,
|
|
293
|
-
writeLock,
|
|
294
|
-
trackingKey,
|
|
295
|
-
marked,
|
|
296
|
-
hidden,
|
|
297
|
-
closed,
|
|
298
|
-
allowChannel
|
|
299
|
-
} = update;
|
|
300
|
-
const hasMultiple = Array.isArray(runKey) && runKey.length > 1;
|
|
301
|
-
const uriComponent = hasMultiple ? '' : `/${runKey.length === 1 ? runKey[0] : runKey}`;
|
|
302
|
-
const permit = readLock || writeLock ? {
|
|
303
|
-
readLock,
|
|
304
|
-
writeLock
|
|
305
|
-
} : undefined;
|
|
306
|
-
return await new Router().withSearchParams(hasMultiple ? {
|
|
307
|
-
runKey
|
|
308
|
-
} : '').patch(`/run${uriComponent}`, {
|
|
309
|
-
body: {
|
|
310
|
-
permit,
|
|
311
|
-
trackingKey,
|
|
312
|
-
marked,
|
|
313
|
-
hidden,
|
|
314
|
-
closed,
|
|
315
|
-
allowChannel
|
|
316
|
-
},
|
|
317
|
-
...optionals
|
|
318
|
-
}).then(({
|
|
319
|
-
body
|
|
320
|
-
}) => body);
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* *Does not actually delete the run*. The run is instead removed from memory. This can be used as a means of preserving server CPUs, and should be used when you do not expect to perform any additional actions that would bring the run back into memory.
|
|
325
|
-
* Base URL: DELETE `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/{RUN_KEY}`
|
|
326
|
-
*
|
|
327
|
-
* @example
|
|
328
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
329
|
-
* await runAdapter.remove('00000173078afb05b4ae4c726637167a1a9e');
|
|
330
|
-
*
|
|
331
|
-
* @param runKey Key associated with the run
|
|
332
|
-
* @param [optionals] Optional arguments; pass network call options overrides here.
|
|
333
|
-
* @returns promise that resolve to undefined if successful
|
|
334
|
-
*/
|
|
335
|
-
async function remove(runKey, optionals = {}) {
|
|
336
|
-
return await new Router().delete(`/run/${runKey}`, optionals).then(({
|
|
337
|
-
body
|
|
338
|
-
}) => body);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
/**
|
|
342
|
-
* Gets a specific run by its runKey
|
|
343
|
-
* Base URL: GET `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/{RUN_KEY}`
|
|
344
|
-
*
|
|
345
|
-
* @example
|
|
346
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
347
|
-
* const run = await runAdapter.get('00000173078afb05b4ae4c726637167a1a9e');
|
|
348
|
-
*
|
|
349
|
-
* @param runKey Key associated with the run
|
|
350
|
-
* @param [optionals] Optional arguments; pass network call options overrides here.
|
|
351
|
-
* @returns promise that resolves to the run
|
|
352
|
-
*/
|
|
353
|
-
async function get(runKey, optionals = {}) {
|
|
354
|
-
return await new Router().get(`/run/${runKey}`, optionals).then(({
|
|
355
|
-
body
|
|
356
|
-
}) => body);
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
/**
|
|
360
|
-
* Queries for runs.
|
|
361
|
-
* Base URL: GET `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/{SCOPE_BOUNDARY}/{SCOPE_KEY}/{MODEL}` or GET `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/in/{GROUP_NAME}/{MODEL}` or GET `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/in/{GROUP_NAME}/{EPISODE_NAME}/{MODEL}`
|
|
362
|
-
*
|
|
363
|
-
* @example
|
|
364
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
365
|
-
* const page = await runAdapter.query('model.xlsx', {
|
|
366
|
-
* filter: [
|
|
367
|
-
* 'var.foo|=1|2|3', // look for runs with a variable 'foo' with the values 1, 2, or 3
|
|
368
|
-
* 'var.score>=24', // looks for runs with a variable 'score' higher than or equal to 24
|
|
369
|
-
* 'var.certified*=true' // looks for runs where the variable 'certified' exists,
|
|
370
|
-
* 'run.hidden=false', // where the run's 'hidden' attribute is false
|
|
371
|
-
* 'meta.classification~=bar-*' // where the run metadata contains a 'classification' that begins with 'bar-',
|
|
372
|
-
* 'meta.categorization~=*-baz' // where the run metadata contains a 'categorization' that does not end with '-baz',
|
|
373
|
-
* ],
|
|
374
|
-
* sort: ['+run.created'] // sort all findings by the 'created' field (ascending)
|
|
375
|
-
* variables: ['foo', 'baz'], // include the run variables for 'foo' and 'baz' in the response
|
|
376
|
-
* metadata: ['classification'] // include the run metadata for 'classification' in the response
|
|
377
|
-
* });
|
|
378
|
-
*
|
|
379
|
-
* @param model Name of your model file
|
|
380
|
-
* @param searchOptions Search options
|
|
381
|
-
* @param [searchOptions.scope.scopeBoundary] Scope boundary, defines the type of scope; See [scope boundary](#SCOPE_BOUNDARY) for all types
|
|
382
|
-
* @param [searchOptions.scope.scopeKey] Scope key, a unique identifier tied to the scope. E.g., if your `scopeBoundary` is `GROUP`, your `scopeKey` will be your `groupKey`; for `EPISODE`, `episodeKey`, etc.
|
|
383
|
-
* @param [searchOptions.scope.userKey] User attached to scope if necessary
|
|
384
|
-
* @param [searchOptions.filter] List of conditionals to filter for
|
|
385
|
-
* @param [searchOptions.sort] List of values to sort by (applies only to run attributes)
|
|
386
|
-
* @param [searchOptions.variables] List of variables to include with the runs found
|
|
387
|
-
* @param [searchOptions.metadata] List of metadata to include with the runs found
|
|
388
|
-
* @param [searchOptions.first] The index from which we collect our runs from
|
|
389
|
-
* @param [searchOptions.max] The maximum number of runs to return (upper limit: 200)
|
|
390
|
-
* @param [searchOptions.timeout] Number of seconds we're willing to wait for the response from the server
|
|
391
|
-
* @param [searchOptions.includeEpisodes] Only used for the `run/in/groupName` endpoint
|
|
392
|
-
* @param [optionals] Optional arguments; pass network call options overrides here.
|
|
393
|
-
* @returns promise that resolves to a page of runs
|
|
394
|
-
*/
|
|
395
|
-
async function query(model, searchOptions, optionals = {}) {
|
|
396
|
-
const {
|
|
397
|
-
filter,
|
|
398
|
-
sort = [],
|
|
399
|
-
first,
|
|
400
|
-
max,
|
|
401
|
-
timeout,
|
|
402
|
-
variables = [],
|
|
403
|
-
metadata = [],
|
|
404
|
-
scope,
|
|
405
|
-
groupName,
|
|
406
|
-
episodeName,
|
|
407
|
-
includeEpisodes
|
|
408
|
-
} = searchOptions;
|
|
409
|
-
const session = identification.session;
|
|
410
|
-
const uriComponent = scope ? `${scope.scopeBoundary}/${scope.scopeKey}` : `in/${groupName !== null && groupName !== void 0 ? groupName : session === null || session === void 0 ? void 0 : session.groupName}${episodeName ? `/${episodeName}` : ''}`;
|
|
411
|
-
|
|
412
|
-
// Handle additional filters that need to be added programmatically
|
|
413
|
-
let finalFilter = filter;
|
|
414
|
-
if (scope !== null && scope !== void 0 && scope.userKey) {
|
|
415
|
-
const userKeyFilter = `run.userKey=${scope.userKey}`;
|
|
416
|
-
if (Array.isArray(filter)) {
|
|
417
|
-
finalFilter = [...filter, userKeyFilter];
|
|
418
|
-
} else if (typeof filter === 'string') {
|
|
419
|
-
finalFilter = filter ? `${filter};${userKeyFilter}` : userKeyFilter;
|
|
420
|
-
} else if (filter && typeof filter === 'object') {
|
|
421
|
-
// For FilterGroup objects, wrap the existing filter and the userKey filter in an AND group
|
|
422
|
-
finalFilter = {
|
|
423
|
-
type: 'and',
|
|
424
|
-
filters: [filter, userKeyFilter]
|
|
425
|
-
};
|
|
426
|
-
} else {
|
|
427
|
-
finalFilter = [userKeyFilter];
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
const searchParams = {
|
|
431
|
-
filter: parseFilterInput(finalFilter),
|
|
432
|
-
sort: sort.join(';') || undefined,
|
|
433
|
-
var: variables.join(';') || undefined,
|
|
434
|
-
meta: metadata.join(';') || undefined,
|
|
435
|
-
first,
|
|
436
|
-
max,
|
|
437
|
-
timeout,
|
|
438
|
-
includeEpisodes
|
|
439
|
-
};
|
|
440
|
-
return await new Router().withSearchParams(searchParams).get(`/run/${uriComponent}/${model}`, {
|
|
441
|
-
paginated: true,
|
|
442
|
-
parsePage: values => {
|
|
443
|
-
return values.map(run => {
|
|
444
|
-
run.variables = variables.reduce((variableMap, key, index) => {
|
|
445
|
-
var _run$variables;
|
|
446
|
-
// TODO -- add a test case to run.spec that makes sure it does not error if it receives run w/o 'variables'
|
|
447
|
-
variableMap[key] = (_run$variables = run.variables) === null || _run$variables === void 0 ? void 0 : _run$variables[index];
|
|
448
|
-
return variableMap;
|
|
449
|
-
}, {});
|
|
450
|
-
return run;
|
|
451
|
-
});
|
|
452
|
-
},
|
|
453
|
-
...optionals
|
|
454
|
-
}).then(({
|
|
455
|
-
body
|
|
456
|
-
}) => body);
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
/**
|
|
460
|
-
* Retrieves a model's introspection information based on model file.
|
|
461
|
-
* The exact structure of the information returned varies between model languages, but generally includes information about the model's variables (data type, whether they are user-accessible/writable, etc), named ranges, available model functions. SimLang models also provide "causes" and "effects" for variables, which are ways of describing which variables are affected by changes to other variables.
|
|
462
|
-
* Base URL: GET `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/introspect/model/{MODEL}`
|
|
463
|
-
*
|
|
464
|
-
* @example
|
|
465
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
466
|
-
* const info = await runAdapter.introspect('model.py');
|
|
467
|
-
*
|
|
468
|
-
* @param model Name of your model file
|
|
469
|
-
* @param [optionals] Optional arguments; pass network call options overrides here.
|
|
470
|
-
* @returns promise that resolves to an object containing the model's introspection information
|
|
471
|
-
*/
|
|
472
|
-
async function introspect(model, optionals = {}) {
|
|
473
|
-
return await new Router().get(`/run/introspect/model/${model}`, optionals).then(({
|
|
474
|
-
body
|
|
475
|
-
}) => body);
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
/**
|
|
479
|
-
* Retrieves a model's introspection information based on a run key associated with the model.
|
|
480
|
-
* The exact structure of the information returned varies between model languages, but generally includes information about the model's variables (data type, whether they are user-accessible/writable, etc), named ranges, available model functions. SimLang models also provide "causes" and "effects" for variables, which are ways of describing which variables are affected by changes to other variables.
|
|
481
|
-
* Base URL: GET `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/introspect/{RUN_KEY}`
|
|
482
|
-
*
|
|
483
|
-
* @example
|
|
484
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
485
|
-
* const info = await runAdapter.introspectWithRunKey('00000173078afb05b4ae4c726637167a1a9e');
|
|
486
|
-
*
|
|
487
|
-
* @param runKey Identifier for your run
|
|
488
|
-
* @param [optionals] Optional arguments; pass network call options overrides here.
|
|
489
|
-
* @returns promise that resolves to an object containing the model's introspection information
|
|
490
|
-
*/
|
|
491
|
-
async function introspectWithRunKey(runKey, optionals = {}) {
|
|
492
|
-
return await new Router().get(`/run/introspect/${runKey}`, optionals).then(({
|
|
493
|
-
body
|
|
494
|
-
}) => body);
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
/**
|
|
498
|
-
* Executes an operation on a run.
|
|
499
|
-
* Base URL: POST `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/operation/{RUN_KEY}` or POST `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/operation` (for multiple runs)
|
|
500
|
-
*
|
|
501
|
-
* @example
|
|
502
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
503
|
-
* const result = await runAdapter.operation('00000173078afb05b4ae4c726637167a1a9e', 'simulate', [10]);
|
|
504
|
-
*
|
|
505
|
-
* @param runKey Identifier for your run
|
|
506
|
-
* @param name Name of the operation to execute
|
|
507
|
-
* @param [args] Arguments to pass to the operation
|
|
508
|
-
* @param [optionals] Optional arguments; pass network call options overrides here. Special arguments specific to this method are listed below if they exist.
|
|
509
|
-
* @param [optionals.timeout] Number of seconds we're willing to wait for the response from the server
|
|
510
|
-
* @param [optionals.ritual] Ritual describing how to store and remove the run from memory; one of the strings defined in RITUAL
|
|
511
|
-
* @returns promise that resolve to the operation's return value
|
|
512
|
-
*/
|
|
513
|
-
async function operation(runKey, name, args = [], optionals = {}) {
|
|
514
|
-
const {
|
|
515
|
-
timeout,
|
|
516
|
-
ritual,
|
|
517
|
-
...routingOptions
|
|
518
|
-
} = optionals;
|
|
519
|
-
const hasMultiple = Array.isArray(runKey) && runKey.length > 1;
|
|
520
|
-
const uriComponent = hasMultiple ? '' : `/${runKey.length === 1 ? runKey[0] : runKey}`;
|
|
521
|
-
const searchParams = hasMultiple ? {
|
|
522
|
-
runKey,
|
|
523
|
-
timeout
|
|
524
|
-
} : {
|
|
525
|
-
ritual,
|
|
526
|
-
timeout
|
|
527
|
-
};
|
|
528
|
-
if (ritual !== RITUAL.EXORCISE && hasMultiple) {
|
|
529
|
-
console.warn(`Detected ritual: ${ritual} usage with multiple runKeys; this not allowed. Defaulting to ritual: EXORCISE`);
|
|
530
|
-
}
|
|
531
|
-
return await new Router().withSearchParams(searchParams).post(`/run/operation${uriComponent}`, {
|
|
532
|
-
body: {
|
|
533
|
-
name,
|
|
534
|
-
arguments: args,
|
|
535
|
-
objectType: 'execute' // TODO: remove this when platform fixes this so that it's not manually required
|
|
536
|
-
},
|
|
537
|
-
...routingOptions
|
|
538
|
-
}).then(({
|
|
539
|
-
body
|
|
540
|
-
}) => body);
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
/**
|
|
544
|
-
* Retrieves model variables for a run or runs
|
|
545
|
-
* Base URL: POST `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/variable/{RUN_KEY}` or POST `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/variable` (for multiple runs)
|
|
546
|
-
*
|
|
547
|
-
* @example
|
|
548
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
549
|
-
* // Single runKey
|
|
550
|
-
* const vars = await runAdapter.getVariables('00000173078afb05b4ae4c726637167a1a9e', ['var1', 'var2']);
|
|
551
|
-
* // Multiple runKeys
|
|
552
|
-
* const varsArray = await runAdapter.getVariables(['00000173078afb05b4ae4c726637167a1a9e', '0000017dd3bf540e5ada5b1e058f08f20461'], ['var1', 'var2']);
|
|
553
|
-
*
|
|
554
|
-
* @param runKey Identifier for your run or runs
|
|
555
|
-
* @param variables List of variables to retrieve
|
|
556
|
-
* @param [optionals] Optional arguments; pass network call options overrides here. Special arguments specific to this method are listed below if they exist.
|
|
557
|
-
* @param [optionals.timeout] Number of seconds we're willing to wait for the response from the server
|
|
558
|
-
* @param [optionals.ritual] Ritual describing how to store and remove the run from memory; one of the strings defined in RITUAL
|
|
559
|
-
* @param [optionals.ignorable] If true, suppresses errors when variables are not found
|
|
560
|
-
* @returns promise that resolve to an object with the variables and their values
|
|
561
|
-
*/
|
|
562
|
-
async function getVariables(runKey, variables, optionals = {}) {
|
|
563
|
-
const {
|
|
564
|
-
timeout,
|
|
565
|
-
ritual,
|
|
566
|
-
ignorable,
|
|
567
|
-
...routingOptions
|
|
568
|
-
} = optionals;
|
|
569
|
-
const hasMultiple = Array.isArray(runKey) && runKey.length > 1;
|
|
570
|
-
if (ritual !== RITUAL.EXORCISE && hasMultiple) {
|
|
571
|
-
console.warn(`Detected ritual: ${ritual} usage with multiple runKeys; this not allowed. Defaulting to ritual: EXORCISE`);
|
|
572
|
-
}
|
|
573
|
-
const mappify = values => variables.reduce((variableMap, key, index) => {
|
|
574
|
-
variableMap[key] = values[index];
|
|
575
|
-
return variableMap;
|
|
576
|
-
}, {});
|
|
577
|
-
const uriComponent = hasMultiple ? '' : `/${runKey.length === 1 ? runKey[0] : runKey}`;
|
|
578
|
-
const include = variables.join(';');
|
|
579
|
-
const body = hasMultiple ? {
|
|
580
|
-
runKey,
|
|
581
|
-
include,
|
|
582
|
-
timeout
|
|
583
|
-
} : {
|
|
584
|
-
ritual,
|
|
585
|
-
include,
|
|
586
|
-
timeout
|
|
587
|
-
};
|
|
588
|
-
const additional = ignorable ? {
|
|
589
|
-
ignorable
|
|
590
|
-
} : {};
|
|
591
|
-
return await new Router().post(`/run/variable${uriComponent}`, {
|
|
592
|
-
body: {
|
|
593
|
-
...body,
|
|
594
|
-
...additional
|
|
595
|
-
},
|
|
596
|
-
...routingOptions
|
|
597
|
-
}).then(({
|
|
598
|
-
body
|
|
599
|
-
}) => {
|
|
600
|
-
if (hasMultiple) {
|
|
601
|
-
return Object.keys(body).map(runKey => ({
|
|
602
|
-
runKey,
|
|
603
|
-
variables: mappify(body[runKey])
|
|
604
|
-
}));
|
|
605
|
-
}
|
|
606
|
-
return mappify(body);
|
|
607
|
-
});
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
/**
|
|
611
|
-
* Retrieves model variable(s) for a run or runs
|
|
612
|
-
* Base URL: GET `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/variable/{RUN_KEY}/{VARIABLE}` or POST (for multiple runs/variables)
|
|
613
|
-
*
|
|
614
|
-
* @example
|
|
615
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
616
|
-
* // Single runKey, single variable
|
|
617
|
-
* const value = await runAdapter.getVariable('00000173078afb05b4ae4c726637167a1a9e', 'var1');
|
|
618
|
-
* // Multiple runKeys, multiple variables
|
|
619
|
-
* const varsArray = await runAdapter.getVariable(['00000173078afb05b4ae4c726637167a1a9e', '0000017dd3bf540e5ada5b1e058f08f20461'], ['var1', 'var2']);
|
|
620
|
-
*
|
|
621
|
-
* @param runKey Identifier for your run or runs
|
|
622
|
-
* @param variable Variable or list of variables to retrieve
|
|
623
|
-
* @param [optionals] Optional arguments; pass network call options overrides here. Special arguments specific to this method are listed below if they exist.
|
|
624
|
-
* @param [optionals.timeout] Number of seconds we're willing to wait for the response from the server
|
|
625
|
-
* @param [optionals.ritual] Ritual describing how to store and remove the run from memory; one of the strings defined in RITUAL
|
|
626
|
-
* @returns promise that resolve to the variable's value, or an object with the variables and their values
|
|
627
|
-
*/
|
|
628
|
-
async function getVariable(runKey, variable, optionals = {}) {
|
|
629
|
-
const {
|
|
630
|
-
timeout,
|
|
631
|
-
ritual,
|
|
632
|
-
...routingOptions
|
|
633
|
-
} = optionals;
|
|
634
|
-
if (Array.isArray(runKey) || Array.isArray(variable)) {
|
|
635
|
-
const variables = Array.isArray(variable) ? variable : [variable];
|
|
636
|
-
return getVariables(runKey, variables, optionals);
|
|
637
|
-
}
|
|
638
|
-
return await new Router().withSearchParams({
|
|
639
|
-
timeout,
|
|
640
|
-
ritual
|
|
641
|
-
}).get(`/run/variable/${runKey}/${String(variable)}`, routingOptions).then(({
|
|
642
|
-
body
|
|
643
|
-
}) => body);
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
/**
|
|
647
|
-
* Updates model variables for the run
|
|
648
|
-
* Base URL: PATCH `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/variable/{RUN_KEY}` or PATCH `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/variable` (for multiple runs)
|
|
649
|
-
*
|
|
650
|
-
* @example
|
|
651
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
652
|
-
* const updated = await runAdapter.updateVariables('00000173078afb05b4ae4c726637167a1a9e', {
|
|
653
|
-
* price: 100,
|
|
654
|
-
* foo: 'bar',
|
|
655
|
-
* });
|
|
656
|
-
*
|
|
657
|
-
* @param runKey Identifier for your run
|
|
658
|
-
* @param update Object with the key-value pairs you would like to update in the model
|
|
659
|
-
* @param [optionals] Optional arguments; pass network call options overrides here. Special arguments specific to this method are listed below if they exist.
|
|
660
|
-
* @param [optionals.timeout] Number of seconds we're willing to wait for the response from the server
|
|
661
|
-
* @param [optionals.ritual] Ritual describing how to store and remove the run from memory; one of the strings defined in RITUAL
|
|
662
|
-
* @returns promise that resolve to an object with the variables and new values that were updated
|
|
663
|
-
*/
|
|
664
|
-
async function updateVariables(runKey, update, optionals = {}) {
|
|
665
|
-
const {
|
|
666
|
-
timeout,
|
|
667
|
-
ritual,
|
|
668
|
-
...routingOptions
|
|
669
|
-
} = optionals;
|
|
670
|
-
const hasMultiple = Array.isArray(runKey) && runKey.length > 1;
|
|
671
|
-
const uriComponent = hasMultiple ? '' : `/${runKey.length === 1 ? runKey[0] : runKey}`;
|
|
672
|
-
const searchParams = hasMultiple ? {
|
|
673
|
-
runKey,
|
|
674
|
-
timeout
|
|
675
|
-
} : {
|
|
676
|
-
ritual,
|
|
677
|
-
timeout
|
|
678
|
-
};
|
|
679
|
-
if (ritual !== RITUAL.EXORCISE && hasMultiple) {
|
|
680
|
-
console.warn(`Detected ritual: ${ritual} usage with multiple runKeys; this not allowed. Defaulting to ritual: EXORCISE`);
|
|
681
|
-
}
|
|
682
|
-
return await new Router().withSearchParams(searchParams).patch(`/run/variable${uriComponent}`, {
|
|
683
|
-
body: update,
|
|
684
|
-
...routingOptions
|
|
685
|
-
}).then(({
|
|
686
|
-
body
|
|
687
|
-
}) => body);
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
/**
|
|
691
|
-
* Retrieves run metadata for a run or runs
|
|
692
|
-
* Base URL: POST `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/meta`
|
|
693
|
-
*
|
|
694
|
-
* @example
|
|
695
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
696
|
-
* // Single runKey
|
|
697
|
-
* const meta = await runAdapter.getMetadata('00000173078afb05b4ae4c726637167a1a9e', ['meta1', 'meta2']);
|
|
698
|
-
* // Multiple runKeys
|
|
699
|
-
* const metaArray = await runAdapter.getMetadata(['00000173078afb05b4ae4c726637167a1a9e', '0000017dd3bf540e5ada5b1e058f08f20461'], ['meta1', 'meta2']);
|
|
700
|
-
*
|
|
701
|
-
* @param runKey Identifier for your run or runs
|
|
702
|
-
* @param metadata List of metadata keys to retrieve
|
|
703
|
-
* @param [optionals] Optional arguments; pass network call options overrides here. Special arguments specific to this method are listed below if they exist.
|
|
704
|
-
* @param [optionals.timeout] Number of seconds we're willing to wait for the response from the server
|
|
705
|
-
* @returns promise that resolve to an object with the metadata and their values
|
|
706
|
-
*/
|
|
707
|
-
async function getMetadata(runKey, metadata, optionals = {}) {
|
|
708
|
-
const {
|
|
709
|
-
...routingOptions
|
|
710
|
-
} = optionals;
|
|
711
|
-
const include = metadata.join(';');
|
|
712
|
-
const hasMultiple = Array.isArray(runKey) && runKey.length > 1;
|
|
713
|
-
const runKeyArg = Array.isArray(runKey) ? runKey : [runKey];
|
|
714
|
-
return await new Router().post('/run/meta', {
|
|
715
|
-
body: {
|
|
716
|
-
include,
|
|
717
|
-
runKey: runKeyArg
|
|
718
|
-
},
|
|
719
|
-
...routingOptions
|
|
720
|
-
}).then(({
|
|
721
|
-
body
|
|
722
|
-
}) => {
|
|
723
|
-
var _bodyAsArray$;
|
|
724
|
-
const bodyAsArray = Object.keys(body).map(runKey => ({
|
|
725
|
-
runKey,
|
|
726
|
-
data: body[runKey]
|
|
727
|
-
}));
|
|
728
|
-
return hasMultiple ? bodyAsArray : bodyAsArray === null || bodyAsArray === void 0 || (_bodyAsArray$ = bodyAsArray[0]) === null || _bodyAsArray$ === void 0 ? void 0 : _bodyAsArray$.data;
|
|
729
|
-
});
|
|
730
|
-
}
|
|
731
|
-
/**
|
|
732
|
-
* Updates run metadata for a run or runs
|
|
733
|
-
* Base URL: PATCH `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/meta/{RUN_KEY}` or PATCH `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/meta` (for multiple runs)
|
|
734
|
-
*
|
|
735
|
-
* @example
|
|
736
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
737
|
-
* // Set metadata values
|
|
738
|
-
* const updated = await runAdapter.updateMetadata('00000173078afb05b4ae4c726637167a1a9e', {
|
|
739
|
-
* set: {
|
|
740
|
-
* classification: 'new-classification',
|
|
741
|
-
* categorization: 'new-categorization',
|
|
742
|
-
* },
|
|
743
|
-
* });
|
|
744
|
-
* // Push values to array metadata
|
|
745
|
-
* const pushed = await runAdapter.updateMetadata('00000173078afb05b4ae4c726637167a1a9e', {
|
|
746
|
-
* push: {
|
|
747
|
-
* history: 'new-entry',
|
|
748
|
-
* },
|
|
749
|
-
* });
|
|
750
|
-
* // Pop values from array metadata
|
|
751
|
-
* const popped = await runAdapter.updateMetadata('00000173078afb05b4ae4c726637167a1a9e', {
|
|
752
|
-
* pop: {
|
|
753
|
-
* history: { objectType: 'last' },
|
|
754
|
-
* },
|
|
755
|
-
* });
|
|
756
|
-
*
|
|
757
|
-
* @param runKey Identifier for your run or runs
|
|
758
|
-
* @param update Metadata update operations
|
|
759
|
-
* @param [update.set] Key-value pairs to set in the metadata
|
|
760
|
-
* @param [update.push] Key-value pairs to push to array metadata
|
|
761
|
-
* @param [update.pop] Keys with pop operations (first, last, or all) to remove from array metadata
|
|
762
|
-
* @param [optionals] Optional arguments; pass network call options overrides here. Special arguments specific to this method are listed below if they exist.
|
|
763
|
-
* @param [optionals.timeout] Number of seconds we're willing to wait for the response from the server
|
|
764
|
-
* @returns promise that resolves to an object with the updated metadata
|
|
765
|
-
*/
|
|
766
|
-
async function updateMetadata(runKey, update, optionals = {}) {
|
|
767
|
-
const {
|
|
768
|
-
timeout,
|
|
769
|
-
...routingOptions
|
|
770
|
-
} = optionals;
|
|
771
|
-
const hasMultiple = Array.isArray(runKey) && runKey.length > 1;
|
|
772
|
-
const uriComponent = hasMultiple ? '' : `/${runKey.length === 1 ? runKey[0] : runKey}`;
|
|
773
|
-
const searchParams = hasMultiple ? {
|
|
774
|
-
runKey,
|
|
775
|
-
timeout
|
|
776
|
-
} : {
|
|
777
|
-
timeout
|
|
778
|
-
};
|
|
779
|
-
return await new Router().withSearchParams(searchParams).patch(`/run/meta${uriComponent}`, {
|
|
780
|
-
body: update,
|
|
781
|
-
...routingOptions
|
|
782
|
-
}).then(({
|
|
783
|
-
body
|
|
784
|
-
}) => body);
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
/**
|
|
788
|
-
* Executes a list of actions on a run or runs
|
|
789
|
-
* Base URL: POST `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/action/{RUN_KEY}` or POST `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/action` (for multiple runs)
|
|
790
|
-
*
|
|
791
|
-
* @example
|
|
792
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
793
|
-
* const actions = [
|
|
794
|
-
* { name: 'price', value: 100, 'objectType': 'set' },
|
|
795
|
-
* { name: 'simulate', arguments: [10], 'objectType': 'execute' },
|
|
796
|
-
* ];
|
|
797
|
-
* // Single runKey
|
|
798
|
-
* const result = await runAdapter.action('00000173078afb05b4ae4c726637167a1a9e', actions);
|
|
799
|
-
* // Multiple runKeys
|
|
800
|
-
* const results = await runAdapter.action(['00000173078afb05b4ae4c726637167a1a9e', '0000017dd3bf540e5ada5b1e058f08f20461'], actions);
|
|
801
|
-
*
|
|
802
|
-
* @param runKey Identifier for your run or runs
|
|
803
|
-
* @param actionList List of actions to perform
|
|
804
|
-
* @param [optionals] Optional arguments; pass network call options overrides here. Special arguments specific to this method are listed below if they exist.
|
|
805
|
-
* @param [optionals.timeout] Number of seconds we're willing to wait for the response from the server
|
|
806
|
-
* @param [optionals.ritual] Ritual describing how to store and remove the run from memory; one of the strings defined in RITUAL
|
|
807
|
-
* @returns promise that resolve to an object with the action results
|
|
808
|
-
*/
|
|
809
|
-
async function action(runKey, actionList, optionals = {}) {
|
|
810
|
-
const {
|
|
811
|
-
timeout,
|
|
812
|
-
ritual,
|
|
813
|
-
...routingOptions
|
|
814
|
-
} = optionals;
|
|
815
|
-
const hasMultiple = Array.isArray(runKey) && runKey.length > 1;
|
|
816
|
-
const uriComponent = hasMultiple ? '' : `/${runKey.length === 1 ? runKey[0] : runKey}`;
|
|
817
|
-
const searchParams = hasMultiple ? {
|
|
818
|
-
runKey,
|
|
819
|
-
timeout
|
|
820
|
-
} : {
|
|
821
|
-
ritual,
|
|
822
|
-
timeout
|
|
823
|
-
};
|
|
824
|
-
if (ritual !== RITUAL.EXORCISE && hasMultiple) {
|
|
825
|
-
console.warn(`Detected ritual: ${ritual} usage with multiple runKeys; this not allowed. Defaulting to ritual: EXORCISE`);
|
|
826
|
-
}
|
|
827
|
-
return await new Router().withSearchParams(searchParams).post(`/run/action${uriComponent}`, {
|
|
828
|
-
body: actionList,
|
|
829
|
-
...routingOptions
|
|
830
|
-
}).then(({
|
|
831
|
-
body
|
|
832
|
-
}) => body);
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
/**
|
|
836
|
-
* Returns the run associated with the given world key; brings the run into memory, if the run does not exist, it will create it.
|
|
837
|
-
* See `runAdapter.create` for more information about platform-determined default permits.
|
|
838
|
-
* Base URL: POST `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/world/{WORLD_KEY}`
|
|
839
|
-
*
|
|
840
|
-
* @example
|
|
841
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
842
|
-
* const run = await runAdapter.retrieveFromWorld('0000017a445032dc38cb2cecd5fc13708314', 'model.py');
|
|
843
|
-
*
|
|
844
|
-
* @param worldKey Key associated with the world you'd like a run from
|
|
845
|
-
* @param model Name of model file you'd use to create the run if needed
|
|
846
|
-
* @param [optionals] Optional arguments; pass network call options overrides here. Special arguments specific to this method are listed below if they exist.
|
|
847
|
-
* @param [optionals.readLock] Read permission role; one of the strings defined in ROLE
|
|
848
|
-
* @param [optionals.writeLock] Write permission role; one of the strings defined in ROLE
|
|
849
|
-
* @param [optionals.ephemeral] Used for testing. If true, the run will only exist so long as its in memory; makes it so that nothing is written to the database, history, or variables.
|
|
850
|
-
* @param [optionals.trackingKey] Tracking key
|
|
851
|
-
* @param [optionals.modelContext] .ctx2 file overrides, this is not tracked by clone operations
|
|
852
|
-
* @param [optionals.executionContext] Carries arguments for model file worker on model initialization. This is tracked by clone operations.
|
|
853
|
-
* @param [optionals.allowChannel] Opt into push notifications for this resource. Applicable to projects with phylogeny >= SILENT
|
|
854
|
-
* @returns promise that resolves to the run retrieved from, or created for the world
|
|
855
|
-
*/
|
|
856
|
-
async function retrieveFromWorld(worldKey, model, optionals = {}) {
|
|
857
|
-
const {
|
|
858
|
-
readLock,
|
|
859
|
-
writeLock,
|
|
860
|
-
ephemeral,
|
|
861
|
-
trackingKey,
|
|
862
|
-
modelContext,
|
|
863
|
-
executionContext,
|
|
864
|
-
allowChannel,
|
|
865
|
-
...routingOptions
|
|
866
|
-
} = optionals;
|
|
867
|
-
const hasPermit = readLock || writeLock;
|
|
868
|
-
const headers = Object.assign({}, routingOptions.headers, hasPermit ? {
|
|
869
|
-
'X-Forio-Confirmation': true
|
|
870
|
-
} : {});
|
|
871
|
-
const permit = hasPermit ? {
|
|
872
|
-
readLock,
|
|
873
|
-
writeLock
|
|
874
|
-
} : undefined;
|
|
875
|
-
return await new Router().post(`/run/world/${worldKey}`, {
|
|
876
|
-
body: {
|
|
877
|
-
permit,
|
|
878
|
-
morphology: 'MANY',
|
|
879
|
-
trackingKey,
|
|
880
|
-
modelFile: model,
|
|
881
|
-
modelContext: modelContext || {},
|
|
882
|
-
executionContext: executionContext || {},
|
|
883
|
-
ephemeral,
|
|
884
|
-
allowChannel
|
|
885
|
-
},
|
|
886
|
-
...routingOptions,
|
|
887
|
-
headers
|
|
888
|
-
}).then(({
|
|
889
|
-
body
|
|
890
|
-
}) => body);
|
|
891
|
-
}
|
|
892
|
-
|
|
893
|
-
/**
|
|
894
|
-
* Removes the run associated with the given world key
|
|
895
|
-
* Base URL: DELETE `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/world/{WORLD_KEY}`
|
|
896
|
-
*
|
|
897
|
-
* @example
|
|
898
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
899
|
-
* await runAdapter.removeFromWorld('0000017a445032dc38cb2cecd5fc13708314');
|
|
900
|
-
*
|
|
901
|
-
* @param worldKey Key associated with the world
|
|
902
|
-
* @param [optionals] Optional arguments; pass network call options overrides here.
|
|
903
|
-
* @returns promise that resolves to undefined when successful
|
|
904
|
-
*/
|
|
905
|
-
async function removeFromWorld(worldKey, optionals = {}) {
|
|
906
|
-
return await new Router().delete(`/run/world/${worldKey}`, optionals).then(({
|
|
907
|
-
body
|
|
908
|
-
}) => body);
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
/**
|
|
912
|
-
* Queries for and/or creates a run, depending on the strategy provided.
|
|
913
|
-
*
|
|
914
|
-
* 'reuse-across-sessions' -- will get the most recent run for the given scope, creating it if it does not exist
|
|
915
|
-
* 'reuse-never' -- will create a new run every time
|
|
916
|
-
*
|
|
917
|
-
* @example
|
|
918
|
-
* import { runAdapter, SCOPE_BOUNDARY } from 'epicenter-libs';
|
|
919
|
-
* const run = await runAdapter.getWithStrategy(
|
|
920
|
-
* 'reuse-across-sessions',
|
|
921
|
-
* 'model.py',
|
|
922
|
-
* {
|
|
923
|
-
* scopeBoundary: SCOPE_BOUNDARY.GROUP,
|
|
924
|
-
* scopeKey: '0000017dd3bf540e5ada5b1e058f08f20461',
|
|
925
|
-
* },
|
|
926
|
-
* );
|
|
927
|
-
*
|
|
928
|
-
* @param strategy Strategy to use when retrieving the run
|
|
929
|
-
* @param model Name of your model file
|
|
930
|
-
* @param scope Scope associated with your run
|
|
931
|
-
* @param scope.scopeBoundary Scope boundary, defines the type of scope; See [scope boundary](#SCOPE_BOUNDARY) for all types
|
|
932
|
-
* @param scope.scopeKey Scope key, a unique identifier tied to the scope. E.g., if your `scopeBoundary` is `GROUP`, your `scopeKey` will be your `groupKey`; for `EPISODE`, `episodeKey`, etc.
|
|
933
|
-
* @param [optionals] Optional arguments; pass network call options overrides here. Special arguments specific to this method are listed below if they exist.
|
|
934
|
-
* @param [optionals.readLock] Read permission role; one of the strings defined in ROLE
|
|
935
|
-
* @param [optionals.writeLock] Write permission role; one of the strings defined in ROLE
|
|
936
|
-
* @param [optionals.ephemeral] Used for testing. If true, the run will only exist so long as its in memory; makes it so that nothing is written to the database, history, or variables.
|
|
937
|
-
* @param [optionals.trackingKey] Tracking key
|
|
938
|
-
* @param [optionals.modelContext] .ctx2 file overrides, this is not tracked by clone operations
|
|
939
|
-
* @param [optionals.executionContext] Carries arguments for model file worker on model initialization. This is tracked by clone operations.
|
|
940
|
-
* @returns promise that resolves to a run
|
|
941
|
-
*/
|
|
942
|
-
async function getWithStrategy(strategy, model, scope, optionals = {}) {
|
|
943
|
-
// const { initOperations = [] } = optionals;
|
|
944
|
-
if (strategy === 'reuse-across-sessions') {
|
|
945
|
-
const searchOptions = {
|
|
946
|
-
scope,
|
|
947
|
-
sort: ['-run.created'],
|
|
948
|
-
max: 1
|
|
949
|
-
};
|
|
950
|
-
const {
|
|
951
|
-
values: [lastRun]
|
|
952
|
-
} = await query(model, searchOptions);
|
|
953
|
-
if (!lastRun) {
|
|
954
|
-
const newRun = await create(model, scope, optionals);
|
|
955
|
-
// await serial(newRun.runKey, initOperations, optionals = {});
|
|
956
|
-
return newRun;
|
|
957
|
-
}
|
|
958
|
-
return lastRun;
|
|
959
|
-
} else if (strategy === 'reuse-never') {
|
|
960
|
-
const newRun = await create(model, scope, optionals);
|
|
961
|
-
// await serial(newRun.runKey, initOperations, optionals = {});
|
|
962
|
-
return newRun;
|
|
963
|
-
} else ;
|
|
964
|
-
throw new EpicenterError('Invalid run strategy.');
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
/**
|
|
968
|
-
* Clone a run into a novel episode scope
|
|
969
|
-
* Base URL: POST `https://forio.com/api/v3/{ACCOUNT}/{PROJECT}/run/migrate/to/{EPISODE_KEY}/{RUN_KEY}`
|
|
970
|
-
*
|
|
971
|
-
* @example
|
|
972
|
-
* import { runAdapter } from 'epicenter-libs';
|
|
973
|
-
* const migratedRun = await runAdapter.migrate(
|
|
974
|
-
* '00000173078afb05b4ae4c726637167a1a9e',
|
|
975
|
-
* '0000017dd3bf540e5ada5b1e058f08f20461',
|
|
976
|
-
* );
|
|
977
|
-
*
|
|
978
|
-
* @param runKey Source run key for the run you want to copy and migrate
|
|
979
|
-
* @param episodeKey Destination episode key for the run's new episode scope
|
|
980
|
-
* @param [optionals] Optional arguments; pass network call options overrides here. Special arguments specific to this method are listed below if they exist.
|
|
981
|
-
* @param [optionals.ephemeral] Used for testing. If true, the run will only exist so long as its in memory; makes it so that nothing is written to the database, history, or variables.
|
|
982
|
-
* @param [optionals.trackingKey] Tracking key
|
|
983
|
-
* @param [optionals.modelContext] .ctx2 file overrides, this is not tracked by migrate operations
|
|
984
|
-
* @param [optionals.executionContext] Carries arguments for model file worker on model initialization. This is tracked by migrate operations.
|
|
985
|
-
* @returns promise that resolves to the migrated run
|
|
986
|
-
*/
|
|
987
|
-
async function migrate(runKey, episodeKey, optionals = {}) {
|
|
988
|
-
const {
|
|
989
|
-
ephemeral,
|
|
990
|
-
trackingKey,
|
|
991
|
-
modelContext = {},
|
|
992
|
-
executionContext = {},
|
|
993
|
-
...routingOptions
|
|
994
|
-
} = optionals;
|
|
995
|
-
return await new Router().post(`/run/migrate/to/${episodeKey}/${runKey}`, {
|
|
996
|
-
body: {
|
|
997
|
-
trackingKey,
|
|
998
|
-
modelContext,
|
|
999
|
-
executionContext,
|
|
1000
|
-
ephemeral
|
|
1001
|
-
},
|
|
1002
|
-
...routingOptions
|
|
1003
|
-
}).then(({
|
|
1004
|
-
body
|
|
1005
|
-
}) => body);
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
export { MORPHOLOGY, action, clone, create, createSingular, get, getMetadata, getSingularRunKey, getVariable, getVariables, getWithStrategy, introspect, introspectWithRunKey, migrate, operation, query, remove, removeFromWorld, restore, retrieveFromWorld, rewind, update, updateMetadata, updateVariables };
|