@revoengine/sdk 2.0.0 → 4.0.0

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/README.md CHANGED
@@ -1,17 +1,34 @@
1
1
  # @revoengine/sdk
2
2
 
3
3
  Official Node.js SDK for RevoEngine. It provides the modern `api`, `utils`,
4
- `storage`, and `agents` namespaces, top-level `execute()`, and the `batch` controller in both
4
+ `storage`, `transport`, `vault`, `serviceAccount`, and `agents` namespaces, top-level `execute()`, and the `batch` controller in both
5
5
  Revo-hosted `CUSTOM_NODEJS` components and standalone Node.js applications.
6
6
 
7
7
  Requirements: Node.js 22 or newer.
8
8
 
9
- ## SDK 2.0.0 compatibility
9
+ Development and GitLab CI use Node.js 24.21.0. Run `nvm use` to select the checked-in `.nvmrc`.
10
10
 
11
- This major release synchronizes the complete public SDK contract with the current
12
- platform low-code declarations. Remote calls require a platform runtime that admits
11
+ ## SDK 4.0.0 compatibility
12
+
13
+ SDK 4.0.0 targets RevoEngine 1.8.0. Remove `skipLibs`, `includeLibs` and
14
+ `excludeLibs` from execution configuration; libraries are resolved automatically.
15
+ These names remain valid as ordinary business data outside those configuration
16
+ locations. Upgrade the SDK and target platform together; use SDK 3.0.0 for an
17
+ instance that still runs 1.7.1. Follow the
18
+ [1.8 upgrade guide](https://docs.revoengine.com/developers/upgrading-to-1-8).
19
+
20
+ ## Earlier SDK 3.0.0 migration
21
+
22
+ This major release synchronizes the complete public SDK contract with RevoEngine
23
+ 1.7.1 and removes deprecated compatibility methods and legacy Files types. Remote calls require a platform runtime that admits
13
24
  the bundled contract revision; publishing the SDK alone does not deploy that runtime.
14
- Use SDK 1.0.1 with older deployments until their platform contract is upgraded.
25
+ Use the SDK version supported by the target platform deployment until its contract is upgraded.
26
+
27
+ Storage declarations include physical-line reads, quote-disabled CSV dialects,
28
+ per-record byte limits, and the opt-in `onError: 'skipRow'` read policy. That policy
29
+ skips records with the wrong source column count and returns bounded locations in
30
+ `csvReport`; syntax and record-size errors still abort. The report describes the
31
+ whole source and must not be summed across pages.
15
32
 
16
33
  HTTP Storage requests/responses now use `requestType: 'storage'` and
17
34
  `responseType: 'storage'`, with flat Storage-only `source` / `target` objects.
@@ -21,6 +38,42 @@ network or hosted bridge dispatch. Automation schedules use `{ scheduleFor }`
21
38
  options instead of positional dates. Regenerated types also include the current
22
39
  Storage and database contracts; use those declarations when migrating callers.
23
40
 
41
+ The `transport` namespace exposes `sftpImport`, `sftpExport`, and `sftpCommands`
42
+ with active Secret names or IDs instead of inline credentials. Storage references
43
+ use the same namespace and effective access rules as other file operations.
44
+ Legacy SFTP helpers and the removed thread-goal methods are not exposed by the
45
+ current SDK contract. Refer to the [transfer guide](https://docs.revoengine.com/low-code/sftp)
46
+ for Secret formats and file-transfer examples.
47
+
48
+ This release retains portable Component digest declarations and one readable-relation
49
+ contract for Databases, live Views, and Materialized Views. Use `api.exportDatabase()`
50
+ for all three relation types, and `api.getDatabaseData()` for structured reads.
51
+ Account data uses `metadata` and `metadataAdvanced`; use `vault.get()` for Secret
52
+ values and `storage.*` for file content. The instance-data source list excludes
53
+ legacy Files resources.
54
+
55
+ Database exports can select CSV, TSV, NDJSON, or XLSX. An asynchronous export
56
+ returns its job ID for operation tracking. The import workflow starts with
57
+ `api.importDatabase()`, then permits a reviewed mapping update and an explicit
58
+ `api.commitDatabaseImport()` after preview validation. The generated declarations
59
+ describe the current request and response shapes; the platform still enforces
60
+ permissions and validates source and target state before committing an import.
61
+
62
+ Assistant model inputs follow the current platform: `gpt-6.1-sol` and
63
+ `gpt-6-luna`; Fast mode is supported for Luna. Update older Sol model identifiers.
64
+
65
+ Remote MCP server configurations in this contract use public HTTPS destinations.
66
+ Private-network access is not an accepted SDK setting; review the server URL,
67
+ provider consent, Vault binding, and tool permissions before enabling a plugin.
68
+
69
+ The SDK includes `agents.createResponse()` and the saved Assistant conversation
70
+ contract: `instructions`, `contextMode` and text or validated JSON `responseFormat`.
71
+ The typed answer is in `output.text` or `output.json`; retain the returned thread
72
+ for an ordinary `agents.sendMessage()` continuation. Provider refusal, incomplete
73
+ output and invalid JSON do not become a successful parsed answer.
74
+ Native Assistant SSE handles and `watchMessage()` remain local to managed V8
75
+ Components and are excluded from the remote SDK contract.
76
+
24
77
  ## Choose your runtime
25
78
 
26
79
  | Environment | How to start | Authentication |
@@ -28,14 +81,14 @@ Storage and database contracts; use those declarations when migrating callers.
28
81
  | Revo-hosted `CUSTOM_NODEJS` | Export `async function init(runtime)` | Revo injects an execution-bound runtime; user code receives no API key. |
29
82
  | Standalone Node.js | Create `new RevoClient(options)` | Supply a RevoEngine API key explicitly or through an environment variable. |
30
83
 
31
- Both modes expose the same `api`, `utils`, `storage`, `agents`, `execute`, and `batch`
84
+ Both modes expose the same `api`, `utils`, `storage`, `transport`, `vault`, `serviceAccount`, `agents`, `execute`, and `batch`
32
85
  properties, but return types reflect where the work happens:
33
86
 
34
87
  | Call kind | Revo-hosted | Standalone |
35
88
  | --- | --- | --- |
36
89
  | Execution snapshot, cache, debug, and logging | Synchronous | Throws synchronously because no execution context exists |
37
90
  | Current user and instance | Synchronous injected snapshot | Asynchronous lazy `/api/v1/me` discovery |
38
- | Remote `api`, `storage`, `agents`, and `execute()` calls | Asynchronous | Asynchronous |
91
+ | Remote `api`, `storage`, `transport`, `vault`, `serviceAccount`, `agents`, and `execute()` calls | Asynchronous | Asynchronous |
39
92
  | Local `utils` and `batch.configure()` | Synchronous unless the utility is inherently asynchronous | Same |
40
93
 
41
94
  ## Installation
@@ -52,7 +105,7 @@ RevoEngine pins that version again in the deployment package and injects the
52
105
  runtime into the component entrypoint. Component code does not construct a
53
106
  `RevoClient`.
54
107
 
55
- The platform chooses the hosted package version; publishing SDK 2.0.0 does not
108
+ The platform chooses the hosted package version; publishing a new SDK does not
56
109
  upgrade existing hosted deployments or their generated package pins.
57
110
 
58
111
  Hosted user code receives neither a tenant API key nor the private runtime
@@ -71,7 +124,7 @@ separate initialization method.
71
124
  ```js
72
125
  /** @param {import('@revoengine/sdk').RevoRuntime} runtime */
73
126
  export async function init(runtime) {
74
- const { api, utils, storage, agents, execute, batch } = runtime;
127
+ const { api, utils, storage, vault, agents, execute, batch } = runtime;
75
128
  const { data: rows, next } = await api.getDatabaseData('Sales', {
76
129
  fields: ['saleId', 'customerId', 'total', 'createdAt'],
77
130
  sort: ['-createdAt'],
@@ -102,14 +155,16 @@ JavaScript ignores the additional runtime argument.
102
155
 
103
156
  Hosted context comes from the current execution snapshot and is synchronous, just
104
157
  like the low-code surface. Only platform-backed work returns a promise.
158
+ Account metadata is available through `currentUser.metadata` and
159
+ `currentUser.metadataAdvanced`.
105
160
 
106
161
  ```js
107
162
  export async function init(runtime) {
108
- const { api } = runtime;
163
+ const { api, vault } = runtime;
109
164
  const input = api.input();
110
165
  const currentUser = api.currentUser();
111
166
  const instance = api.getInstanceDetails();
112
- const signingSecret = await api.getSecret('WEBHOOK_SIGNING_SECRET');
167
+ const signingSecret = (await vault.get('WEBHOOK_SIGNING_SECRET', { scope: 'instance' })).revision.value;
113
168
 
114
169
  api.log({
115
170
  message: 'Processing custom component',
@@ -129,6 +184,8 @@ Execution-only methods such as `api.input()`, `api.getContext()`,
129
184
  `api.getExecutionId()`, and `api.getOperationId()` are available only in hosted
130
185
  executions.
131
186
 
187
+ Use `runtime.execute(code, { readOnly: true })` for transient code that must not write platform state. `readOnly: false` selects full execution for an authorized standalone client; a hosted execution inherits its mode and cannot escalate a restricted parent.
188
+
132
189
  ### Configure hosted batching
133
190
 
134
191
  Configure batching before the first remote call:
@@ -196,7 +253,7 @@ There is no `init()` or connection method.
196
253
  ## Execute active low-code libraries
197
254
 
198
255
  `execute(code, options)` runs one transient JavaScript or TypeScript component inside
199
- RevoEngine. The source has the normal low-code `api` and active tenant `libs.*`
256
+ RevoEngine. The source has the normal low-code `api` and active tenant `lib.*`
200
257
  surface. Library functions and source never move into the Node.js process; only the
201
258
  JSON-serializable request and execution result cross the runtime transport.
202
259
 
@@ -209,8 +266,8 @@ export async function init(runtime) {
209
266
  const execution = await runtime.execute(
210
267
  `
211
268
  const customerId = api.input('customerId');
212
- const customer = await libs.Customers.Queries.get(customerId);
213
- const balance = await libs.Billing.Balance.current(customerId);
269
+ const customer = await lib.Customers.Queries.get(customerId);
270
+ const balance = await lib.Billing.Balance.current(customerId);
214
271
  return { customer, balance };
215
272
  `,
216
273
  {
@@ -245,7 +302,7 @@ type CustomerSummary = {
245
302
  const execution = await revo.execute<CustomerSummary>(
246
303
  `
247
304
  const customerId = api.input('customerId');
248
- return libs.Customers.Summary.build(customerId);
305
+ return lib.Customers.Summary.build(customerId);
249
306
  `,
250
307
  {
251
308
  inputs: { customerId: 'customer-1' },
@@ -259,7 +316,7 @@ console.log(execution.results);
259
316
  JavaScript is selected with `language: 'javascript'`; TypeScript is the default.
260
317
  The default timeout is 60 seconds. Standalone `executionDefaults` set reusable
261
318
  language, timeout, or memory defaults, and per-call options override them.
262
- One `execute()` call creates one isolated execution. Put related `libs.*`
319
+ One `execute()` call creates one isolated execution. Put related `lib.*`
263
320
  operations in the same source when they belong to one workflow. Concurrent separate
264
321
  calls still use the SDK's automatic JSON-RPC batching but execute in separate isolates.
265
322
  Low-code runtime batches are not retried because source can perform writes.
@@ -317,11 +374,12 @@ Calls queued in the same microtask are grouped. `Promise.all` is the normal way
317
374
  to issue a batch:
318
375
 
319
376
  ```ts
320
- const [customers, crmToken, activeAgents] = await Promise.all([
377
+ const [customers, crmSecret, activeAgents] = await Promise.all([
321
378
  revo.api.getDatabaseData('Customers', { take: 100 }),
322
- revo.api.getSecret('CRM_API_TOKEN'),
379
+ revo.vault.get('CRM_API_TOKEN', { scope: 'instance' }),
323
380
  revo.agents.list(),
324
381
  ]);
382
+ const crmToken = crmSecret.revision.value;
325
383
  ```
326
384
 
327
385
  Sequential `await` statements naturally produce separate batches:
@@ -387,7 +445,8 @@ export async function init(runtime) {
387
445
  args: { userId: currentUser.userId, instanceId, hasInput: input != null },
388
446
  });
389
447
 
390
- return runtime.api.getSecret('SIGNING_SECRET');
448
+ const signingSecret = await runtime.vault.get('SIGNING_SECRET', { scope: 'instance' });
449
+ return { configured: Boolean(signingSecret.revision.value) };
391
450
  }
392
451
  ```
393
452
 
@@ -763,3 +822,85 @@ Common subclasses include:
763
822
  - Deprecated low-code methods and aliases are excluded.
764
823
  - `api.transactionDatabaseData` is excluded.
765
824
  - Runtime batches are non-transactional and are not retried automatically.
825
+
826
+ ## Vault manager
827
+
828
+ The native `client.vault` manager uses the same get/create/update/delete/rotate
829
+ contract for instance (default) and verified user scope. Get alone returns
830
+ `secret.revision.value` as a Buffer containing the stored UTF-8 text; Rotate returns metadata without values.
831
+ Revision versions are normalized validFrom timestamps. validFrom accepts null,
832
+ Date, ISO or epoch milliseconds; a future Rotate preserves current availability.
833
+ `listRevisions` exposes paginated metadata history.
834
+
835
+ ```ts
836
+ const secret = await client.vault.get('TOKEN', { scope: 'user' });
837
+ const token = secret.revision.value.toString('utf8');
838
+ await client.vault.rotate('TOKEN', { value: replacement }, { scope: 'user', validFrom: null });
839
+ ```
840
+
841
+ Do not log values or access tokens. Instance access requires Secret roles and
842
+ creator ownership or administrator rights. User scope uses the verified account;
843
+ management requires owner rights and does not inherit saved Component/Tool grants.
844
+ Writes throw `READ_ONLY_OPERATION_FORBIDDEN` when the execution has `readOnly: true`. See the
845
+ [Vault guide](https://docs.revoengine.com/low-code/reference/vault) for all methods.
846
+
847
+ The same flat manager exposes `getAccessToken`, `getIntegrationMetadata`,
848
+ `discoverIntegration`, `connectIntegration`, and `disconnectIntegration`. Token reads
849
+ return the access token with its matching ISO expiry and refresh when necessary.
850
+ Connect requires nullable `expectedRevision` (null to create) and returns an
851
+ authorization URL for interactive consent through the existing frontend callback.
852
+ Disconnect retains definition/history/grants and does not revoke provider access.
853
+ Saved Component/Tool reads preserve exact personal grants; direct SDK owner/admin
854
+ reads and management are authorized separately.
855
+
856
+
857
+ ## Bulk Jobs and Webhooks
858
+
859
+ Use `api.cancelJobs`, `retryJobs`, `deleteJobs`, `cancelWebhooks`, `retryWebhooks`,
860
+ and `deleteWebhooks` with exactly one non-empty platform `filter` or an ID array
861
+ (`jobIds` / `webhookIds`, 1–1000 IDs). A filter selects every matching row beyond
862
+ list pagination. An optional actor-scoped `idempotencyKey` protects repeat admission.
863
+ The SDK never automatically retries mutations.
864
+
865
+ ```ts
866
+ const input = {
867
+ filter: { field: 'status', op: 'eq', value: 'ERROR' },
868
+ idempotencyKey: 'retry-errors-2026-10-01',
869
+ };
870
+ const preview = await client.api.previewAutomationOperation('jobs', 'retry', input);
871
+ // Review advisory preview.matched / preview.eligible before submitting.
872
+ const operation = await client.api.retryJobs(input);
873
+ const progress = await client.api.getAutomationOperation(operation.operationId);
874
+ const outcomes = await client.api.getAutomationOperationItems(operation.operationId);
875
+ // Fetch subsequent pages with outcomes.nextCursor as the second argument.
876
+ ```
877
+
878
+ Operations report `PENDING`, `PROCESSING`, `FINISHED`, or `ERROR`, plus
879
+ `total`, `processed`, `skipped`, and `failed`. `FINISHED` means lifecycle requests
880
+ were processed; downstream execution/delivery may continue and failed can be non-zero.
881
+ Item pages contain safe source/result IDs and error codes. Preview is advisory;
882
+ admission freezes selection and the worker rechecks state and permissions.
883
+ Cancel/delete require Automation Admin; retry accepts Automation Runner/Admin.
884
+
885
+ `retryWebhooks` accepts `requestPatch`: url/method/body replace whole fields;
886
+ headers/query accept `set` and `remove`, and `maskDetails` adds masks while preserving
887
+ existing masks. Masked original values cannot be recovered: provide explicit
888
+ replacements or the item fails with `REPLAY_PAYLOAD_UNAVAILABLE`. If the entire
889
+ headers section was masked, `headers.set` supplies its complete replacement.
890
+ Request patches are limited to 1 MiB of serialized JSON. Never log replacement
891
+ credentials. The operation result does not expose saved request bodies.
892
+
893
+ ```ts
894
+ await client.api.retryWebhooks({
895
+ webhookIds: selectedWebhookIds,
896
+ idempotencyKey: retryAdmissionKey,
897
+ requestPatch: {
898
+ headers: { set: { Authorization: `Bearer ${replacementToken}` }, remove: ['X-Old-Key'] },
899
+ query: { set: { apiVersion: '2' }, remove: ['legacy'] },
900
+ maskDetails: ['headers.Authorization'],
901
+ },
902
+ });
903
+ ```
904
+
905
+ The target platform requires the bulk-operation migration and an active API worker
906
+ lane. Publishing this SDK does not deploy them or change the hosted SDK pin.