@verentis/sdk 0.1.1 → 0.2.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 +143 -8
- package/dist/index.cjs +571 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +527 -6
- package/dist/index.d.ts +527 -6
- package/dist/index.js +568 -41
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,6 +10,112 @@ npm install @verentis/sdk
|
|
|
10
10
|
|
|
11
11
|
## Quick Start
|
|
12
12
|
|
|
13
|
+
### Consented Marketplace installation graphs
|
|
14
|
+
|
|
15
|
+
Installation administration uses a **workspace-bound user token**, not an iframe's delegated
|
|
16
|
+
app token or an API key. The token needs `marketplace.install.create` for preview/install and
|
|
17
|
+
`marketplace.install.read` for outcomes, plus the Node/Resource installer scopes documented by
|
|
18
|
+
Marketplace. Explicit recovery also needs `marketplace.install.update` and `node.file.delete`.
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
const preview = await client.installations.preview(invoicingPackageId, {
|
|
22
|
+
packageVersion: '1.0.0',
|
|
23
|
+
branch: 'main',
|
|
24
|
+
})
|
|
25
|
+
// Display ALL preview.packages: publisher, version, treeDigest, permissions,
|
|
26
|
+
// manifestYaml, installMode, branch, installPaths, reuse/recovery IDs.
|
|
27
|
+
// Only after the user explicitly agrees to this exact displayed preview:
|
|
28
|
+
const result = await client.installations.install(preview, true)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`preview()` does not install or grant capability authority. Dependencies use canonical
|
|
32
|
+
`publisher/package-id` identities and exact SemVer pins; optional CRM is never implicit.
|
|
33
|
+
`install()` consumes the exact stored fingerprint once. Stale graphs, changed live package
|
|
34
|
+
content/permissions/signing or withdrawn eligibility are rejected, never silently expanded.
|
|
35
|
+
HTTP failures propagate as the existing `ApiError`, including their response body.
|
|
36
|
+
|
|
37
|
+
After a failure or lost response, inspect
|
|
38
|
+
`await client.installations.graphResult(preview.operationId)` instead of repeating `install()`.
|
|
39
|
+
The durable result includes the exact package baseline and per-package outcomes/ledger IDs.
|
|
40
|
+
Installation is not atomic: installed/shared dependencies and retained data are not rolled back.
|
|
41
|
+
A Failed exact target needs a **new** preview and explicit recovery consent; uncertain
|
|
42
|
+
Installing/Updating targets require ledger/operator investigation.
|
|
43
|
+
Dependency-free `update()` / `uninstall()` remain available; updates cannot bypass declared
|
|
44
|
+
dependency consent. WOPI, hosted services and transactional email retain their separate
|
|
45
|
+
verified capability-consent flows. A graph checkbox or unsigned Canvas document is not
|
|
46
|
+
signature proof or financial/email authority.
|
|
47
|
+
|
|
48
|
+
### Hosted header actions (SDK 0.2)
|
|
49
|
+
|
|
50
|
+
Applications register buttons after `await client.whenReady()`. The workspace owns their
|
|
51
|
+
presentation; handlers execute inside the application with its existing delegated token.
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
const save = client.bridge!.registerAction({
|
|
55
|
+
id: 'document.save',
|
|
56
|
+
label: 'Save',
|
|
57
|
+
icon: 'lucide:save',
|
|
58
|
+
variant: 'default',
|
|
59
|
+
scopes: ['node.file.read', 'node.node.create', 'node.node.update', 'node.journal.create'],
|
|
60
|
+
enabled: false,
|
|
61
|
+
}, async () => {
|
|
62
|
+
await persistDocument()
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
// Pass the complete descriptor when document state changes.
|
|
66
|
+
save.update({ id: 'document.save', label: 'Save', scopes: [
|
|
67
|
+
'node.file.read', 'node.node.create', 'node.node.update', 'node.journal.create',
|
|
68
|
+
], enabled: true })
|
|
69
|
+
save.dispose()
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Use stable app-local IDs, up to 16 actions, Lucide icon identifiers, and explicit `scopes`
|
|
73
|
+
(`[]` for client-only operations). `enabled`, `visible`, `busy`, and `disabledReason` communicate
|
|
74
|
+
state without serializing handlers. The host checks required scopes against the delegated grant;
|
|
75
|
+
registration never expands permissions. Throw on failure so the host can display it.
|
|
76
|
+
|
|
77
|
+
For clipboard actions, set `kind: 'clipboard'` and return `{ clipboardText: source }`. The host starts
|
|
78
|
+
the clipboard write in the user's click gesture while awaiting the text, preserving browser
|
|
79
|
+
user-activation requirements. For operations that navigate after completion, return
|
|
80
|
+
`{ navigate: { path: '/applications', newTab: false } }` instead of navigating before the result.
|
|
81
|
+
|
|
82
|
+
The protocol uses session-bound `verentis:actions:set`, `verentis:action:invoke`, and
|
|
83
|
+
`verentis:action:result` messages. Reload/navigation disposes pending work; an unanswered invocation
|
|
84
|
+
times out as **outcome unknown**, never an automatic retry. App handlers must not report successful
|
|
85
|
+
completion before their mutation finishes.
|
|
86
|
+
|
|
87
|
+
Migrated actions are hosted only: there is no legacy-host or standalone-toolbar fallback.
|
|
88
|
+
Fullscreen apps can hide the host header only when they register no actions. Keep specialized
|
|
89
|
+
controls (zoom, editing modes, contextual forms) within the app.
|
|
90
|
+
|
|
91
|
+
Release the 0.2 SDK before deploying apps that require `^0.2.0`, together with the matching host.
|
|
92
|
+
Local sibling-repository development can link the built SDK; published applications must resolve
|
|
93
|
+
the released SDK from npm.
|
|
94
|
+
|
|
95
|
+
### WOPI editor launch
|
|
96
|
+
|
|
97
|
+
Signed WOPI applications use `Bridge.requestWopiLaunch()` after `waitForInit()`.
|
|
98
|
+
The authenticated workspace parent chooses the installed editor, document,
|
|
99
|
+
branch and action; the child cannot request arbitrary document identities.
|
|
100
|
+
The returned token is scoped to WOPI and is not a normal workspace API token.
|
|
101
|
+
Submit it using a form POST to the validated discovery action, never a URL.
|
|
102
|
+
|
|
103
|
+
`requestWopiSave(generation)`, `getWopiStatus()` and `closeWopiSession()` use the
|
|
104
|
+
same exact-parent, origin/session/request-correlated bridge. A matching durable
|
|
105
|
+
save receipt—not a CODE postMessage alone—is required before clearing dirty state.
|
|
106
|
+
When status reports `continuationAvailable`, `requestWopiContinuation()` asks
|
|
107
|
+
the parent to bind the target of a completed server-owned Save As operation.
|
|
108
|
+
It accepts no document or acquisition IDs. Its `WopiContinuation` result contains
|
|
109
|
+
only document metadata and the persisted target `accessTokenTtl`, not a token,
|
|
110
|
+
action URL or private control credential. The parent obtains the exact existing
|
|
111
|
+
control IDs from authenticated `/derived`; it does not reconstruct a launch,
|
|
112
|
+
including after signing-key rotation. Keep the initial launch/form separate from
|
|
113
|
+
active document metadata, retain CODE's iframe and existing token, and preserve
|
|
114
|
+
unverified edits until a matching target save receipt arrives.
|
|
115
|
+
These methods do not replace `requestBackendCredential()` or ordinary OAuth
|
|
116
|
+
authentication for apps that need workspace APIs. WOPI-only packages need no
|
|
117
|
+
per-editor OAuth client secret.
|
|
118
|
+
|
|
13
119
|
### Standalone mode (local development)
|
|
14
120
|
|
|
15
121
|
```ts
|
|
@@ -79,6 +185,36 @@ credentials and `workspaceId` yourself.
|
|
|
79
185
|
|
|
80
186
|
## API Overview
|
|
81
187
|
|
|
188
|
+
### Revision-safe node content
|
|
189
|
+
|
|
190
|
+
Use stable node IDs and an explicit branch for editing existing records. Read bytes and their
|
|
191
|
+
strong revision together; submit that revision and a caller-owned idempotency key when saving:
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
const snapshot = await client.files.readNodeContent(nodeId, { branch: 'main' })
|
|
195
|
+
const next = await client.files.writeNodeContent(nodeId, {
|
|
196
|
+
branch: 'main',
|
|
197
|
+
revision: snapshot.revision,
|
|
198
|
+
idempotencyKey: crypto.randomUUID(),
|
|
199
|
+
content: editedJson,
|
|
200
|
+
})
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
`getNode(nodeId, { branch })` returns stable metadata, including its unquoted `etag`, which
|
|
204
|
+
`writeNodeContent` also accepts. Node-content writes replace bytes only; they do not create files,
|
|
205
|
+
move paths or change MIME types. Keep the same revision, bytes and operation key for an identical
|
|
206
|
+
retry; a new edit needs a new key. The SDK does not automatically retry or report a stale save as
|
|
207
|
+
successful. `ApiError` is a runtime export and exposes `status`, `detail`, optional `title` and the
|
|
208
|
+
platform's optional machine-readable `code` (for example `revision_mismatch`).
|
|
209
|
+
|
|
210
|
+
Path deletion uses `remove({ path, branch, headStamp?, idempotencyKey?, mode? })` with the routed
|
|
211
|
+
file API. `headStamp` is a **path-binding head stamp**, not the quoted node-content revision.
|
|
212
|
+
The default mode is shallow; request `deep` explicitly for recursive deletion. These options
|
|
213
|
+
do not bypass server authorization or mutation guards and do not introduce financial transactions.
|
|
214
|
+
|
|
215
|
+
Deploy only with a platform release providing the conditional node-content routes. New app
|
|
216
|
+
contracts must not assume a locally present feature-branch API is already deployed.
|
|
217
|
+
|
|
82
218
|
| Export | Description |
|
|
83
219
|
| --- | --- |
|
|
84
220
|
| `createVerentisClient(options?)` | Factory function — creates a configured `VerentisClient` |
|
|
@@ -131,15 +267,14 @@ npm run typecheck
|
|
|
131
267
|
|
|
132
268
|
## Versioning
|
|
133
269
|
|
|
134
|
-
|
|
270
|
+
The release workflow publishes the exact stable version in `package.json` after changes
|
|
271
|
+
merge to `main`. Update both `package.json` and `package-lock.json` when preparing a new
|
|
272
|
+
version; npm versions are immutable.
|
|
135
273
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
- `+semver: feature` or `+semver: minor` — minor bump
|
|
141
|
-
- `+semver: fix` or `+semver: patch` — patch bump (default)
|
|
142
|
-
- `+semver: none` or `+semver: skip` — no bump
|
|
274
|
+
A version older than the current npm `latest` is published under `version-<version>`
|
|
275
|
+
without moving `latest` backwards. Consumers of such a release must install its exact
|
|
276
|
+
version (for example, `npm install @verentis/sdk@0.2.0 --save-exact`), not a caret range
|
|
277
|
+
that can resolve to a different release.
|
|
143
278
|
|
|
144
279
|
## License
|
|
145
280
|
|