@synopackageland/sdk 0.10.2 → 0.10.3
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 +77 -5
- package/dist/i18n/background/zh-CN.json +6 -6
- package/dist/i18n/delegate/de.json +5 -3
- package/dist/i18n/delegate/en.json +5 -3
- package/dist/i18n/delegate/es.json +5 -3
- package/dist/i18n/delegate/fr.json +5 -3
- package/dist/i18n/delegate/it.json +5 -3
- package/dist/i18n/delegate/ja.json +5 -3
- package/dist/i18n/delegate/ko.json +5 -3
- package/dist/i18n/delegate/zh-CN.json +5 -3
- package/dist/i18n/delegate/zh-TW.json +5 -3
- package/dist/i18n/identity/zh-CN.json +5 -5
- package/dist/i18n/save/de.json +15 -17
- package/dist/i18n/save/en.json +15 -17
- package/dist/i18n/save/es.json +15 -17
- package/dist/i18n/save/fr.json +15 -17
- package/dist/i18n/save/it.json +15 -17
- package/dist/i18n/save/ja.json +15 -17
- package/dist/i18n/save/ko.json +15 -17
- package/dist/i18n/save/zh-CN.json +15 -17
- package/dist/i18n/save/zh-TW.json +15 -17
- package/dist/index.js +2355 -2348
- package/dist/native.js +350 -0
- package/dist/src/delegate/BackgroundSavePanel.vue.d.ts +3 -0
- package/dist/src/delegate/BackgroundSaveSettings.vue.d.ts +29 -0
- package/dist/src/delegate/ExecutorSettings.vue.d.ts +1 -2
- package/dist/src/delegate/copy.d.ts +10 -6
- package/dist/src/delegate/executor-setup.d.ts +2 -0
- package/dist/src/delegate/save-copy.d.ts +30 -36
- package/dist/src/delegate/use-executor-setup.d.ts +5 -1
- package/dist/src/delegate/use-scope-approval.d.ts +50 -0
- package/dist/src/dsm/file-station.d.ts +1 -1
- package/dist/src/native/authorization-runtime.d.ts +2 -0
- package/dist/src/native/dsm-version.d.ts +6 -0
- package/dist/src/native/root-runtime.d.ts +34 -0
- package/dist/src/native.d.ts +2 -0
- package/dist/src/protocol/v1.d.ts +7 -1
- package/dist/src/shell/PageActions.vue.d.ts +13 -0
- package/dist/src/shell/app-pages.d.ts +2 -0
- package/dist/src/shell/page-actions.d.ts +3 -0
- package/dist/src/vue.d.ts +2 -0
- package/dist/style.css +1 -1
- package/dist/vue.js +1998 -1735
- package/package.json +7 -3
- package/spec/protocol/v1/README.md +86 -5
- package/spec/protocol/v1/errors.json +8 -0
- package/spec/protocol/v1/timeouts.json +21 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synopackageland/sdk",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.3",
|
|
4
4
|
"description": "Frontend SDK for DSM packages built with synopkgland: headless client and Vue components",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/synopackageland/syno-pkg-land-sdk/tree/main/ts#readme",
|
|
@@ -26,6 +26,10 @@
|
|
|
26
26
|
"import": "./dist/vue.js"
|
|
27
27
|
},
|
|
28
28
|
"./vue/style.css": "./dist/style.css",
|
|
29
|
+
"./native": {
|
|
30
|
+
"types": "./dist/src/native.d.ts",
|
|
31
|
+
"import": "./dist/native.js"
|
|
32
|
+
},
|
|
29
33
|
"./i18n/*": "./dist/i18n/*"
|
|
30
34
|
},
|
|
31
35
|
"files": [
|
|
@@ -40,7 +44,7 @@
|
|
|
40
44
|
},
|
|
41
45
|
"peerDependencies": {
|
|
42
46
|
"@lucide/vue": "^1.48.0",
|
|
43
|
-
"@synopackageland/ui": "^0.9.
|
|
47
|
+
"@synopackageland/ui": "^0.9.5",
|
|
44
48
|
"vue": "^3.5.0"
|
|
45
49
|
},
|
|
46
50
|
"peerDependenciesMeta": {
|
|
@@ -53,7 +57,7 @@
|
|
|
53
57
|
},
|
|
54
58
|
"devDependencies": {
|
|
55
59
|
"@lucide/vue": "1.48.0",
|
|
56
|
-
"@synopackageland/ui": "0.9.
|
|
60
|
+
"@synopackageland/ui": "0.9.5",
|
|
57
61
|
"@types/node": "24.19.2",
|
|
58
62
|
"@vitejs/plugin-vue": "6.0.9",
|
|
59
63
|
"jsdom": "27.4.0",
|
|
@@ -15,6 +15,7 @@ the executor against the vectors here.
|
|
|
15
15
|
| `schema/<op>.json` | JSON Schema (draft 2020-12) of the `params` of each op, with `since` |
|
|
16
16
|
| `errors.json` | Every code: `code`, `kind`, `retryable`, `httpStatus`, `en`, `zh-TW`. The only source of codes; the Go constants are generated from it |
|
|
17
17
|
| `vectors/*.jsonl` | One request per line: `{name, request, policy, state, expect}` |
|
|
18
|
+
| `timeouts.json` | The timeouts of the section Timeouts, in seconds; the SDK's constants and tests read it |
|
|
18
19
|
|
|
19
20
|
## Transport
|
|
20
21
|
|
|
@@ -27,6 +28,38 @@ the executor against the vectors here.
|
|
|
27
28
|
4. The executor MUST answer one line of JSON ending in `\n` and close.
|
|
28
29
|
5. The executor SHOULD close a connection that sends nothing for 15 seconds.
|
|
29
30
|
|
|
31
|
+
## Timeouts
|
|
32
|
+
|
|
33
|
+
Since 0.10.3. Every layer between the browser and a root program waits
|
|
34
|
+
longer than the layer it calls, so the inner answer, or the inner refusal,
|
|
35
|
+
arrives before the outer layer gives up. The margin is 10 seconds between
|
|
36
|
+
the executor and its client and between the client and the request; the
|
|
37
|
+
browser waits 2 seconds past the request (`timeouts.json` holds the values).
|
|
38
|
+
|
|
39
|
+
| Layer | Waits for | Bound |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| Root program (`run.timeout_s`) | its own work | 1–120 s, default 20; the process group is then killed |
|
|
42
|
+
| Executor, `root.run` | the program, then its reply | answers within 130 s (120 + 10) |
|
|
43
|
+
| Executor, every other op | its DSM calls | answers within 30 s |
|
|
44
|
+
| Executor client (Go `delegate.Client`, the bridge runtime's `root.*` and `delegate.*`) | the executor | `root.run` 140 s (`delegate.RootRunTimeout`), every other op 40 s (`delegate.ExecutorTimeout`) |
|
|
45
|
+
| Request (`api.Timeout`, manifest `timeout_seconds`) | the App's backend | default 60 s (`api.DefaultRequestTimeout`), 1–3600 |
|
|
46
|
+
| Browser (`clientTimeout`, the CLI window's `call`) | the request | the request's deadline + 2 s |
|
|
47
|
+
|
|
48
|
+
- The request's deadline ends every inner wait: a client never waits past it.
|
|
49
|
+
An App whose backend awaits `root.run` therefore needs a deadline of at
|
|
50
|
+
least the program's `run.timeout_s` + 20 seconds (the executor's 10 and the
|
|
51
|
+
client's 10), so a 120-second program needs `timeout_seconds` 140; a build
|
|
52
|
+
tool SHOULD refuse less. The default 60 covers programs of up to 40 seconds.
|
|
53
|
+
- A client that gave up does not stop the work: `root.run` runs on (it cannot
|
|
54
|
+
be canceled), and `portal.register` and `portal.unregister` finish their
|
|
55
|
+
steps within 2 minutes. The client reads the result again (`status`,
|
|
56
|
+
`root.jobs.get`) instead of repeating the work.
|
|
57
|
+
- The start step (Package start step) is waited on by no request: while it
|
|
58
|
+
runs (at most 60 seconds) every op but `status` is refused at once with
|
|
59
|
+
`EXECUTOR_STARTING` (retryable). A window that waits for the executor to
|
|
60
|
+
become ready polls `status` for longer than 60 seconds before it reports
|
|
61
|
+
the start step as still running.
|
|
62
|
+
|
|
30
63
|
## Request
|
|
31
64
|
|
|
32
65
|
```json
|
|
@@ -78,7 +111,9 @@ and `policy_digest`. With `auth` (since 0.9.6) it also answers `allowed`:
|
|
|
78
111
|
whether DSM's Application Privileges let the caller use the App and File
|
|
79
112
|
Station from `remote_addr`, the check `delegate.create` makes; an invalid
|
|
80
113
|
session is `AUTH_DENIED`. A CGI sends the caller's `auth` so an App the
|
|
81
|
-
executor would refuse is never shown as ready.
|
|
114
|
+
executor would refuse is never shown as ready. While a due start step runs
|
|
115
|
+
(see Package start step), `status` answers `ready: false` with `state`
|
|
116
|
+
`"starting"` and both digests. The executor MUST NOT report the SDK version; the binary
|
|
82
117
|
digest MUST change only when the executor source changes.
|
|
83
118
|
|
|
84
119
|
## Application Portal
|
|
@@ -136,7 +171,7 @@ Every root program, whatever starts it:
|
|
|
136
171
|
| Variable | Set for | Value |
|
|
137
172
|
|---|---|---|
|
|
138
173
|
| `SYNOPKGLAND_PACKAGE` | all | the package name |
|
|
139
|
-
| `SYNOPKGLAND_ROOT_MODE` | all | `run`, `job`, `stop` or `purge` |
|
|
174
|
+
| `SYNOPKGLAND_ROOT_MODE` | all | `run`, `job`, `start`, `stop` or `purge` |
|
|
140
175
|
| `SYNOPKGLAND_REQUESTED_BY` | run, job | the verified DSM user name |
|
|
141
176
|
| `SYNOPKGLAND_REQUEST_ID` | run | 64 hex digits, unique per call |
|
|
142
177
|
| `SYNOPKGLAND_JOB_ID` | job | the job's `job_id` |
|
|
@@ -155,11 +190,16 @@ Every root program, whatever starts it:
|
|
|
155
190
|
- A program that exits, whatever its status, is a result: `request_id`,
|
|
156
191
|
`exit_code`, `stderr` and either `output` (UTF-8, in a reply under 64 KiB)
|
|
157
192
|
or `staging` and `size`, a package-owned staging file the client reads and
|
|
158
|
-
removes.
|
|
193
|
+
removes. `staging` is a bare file name, `root-` and 32 lowercase hex
|
|
194
|
+
digits, never a path: the client joins it to the package staging folder,
|
|
195
|
+
`/var/packages/<package>/var/executor-staging`. The executor MUST create
|
|
196
|
+
that folder, owned by the package account with mode 0700, when it is
|
|
197
|
+
missing; a staging folder it cannot use is `ROOT_FAILED` with the message
|
|
198
|
+
`root output staging unavailable`. Past the timeout the process group is killed (`ROOT_TIMEOUT`);
|
|
159
199
|
output past `max_output` is `limit-exceeded`; a full staging quota is
|
|
160
200
|
`ROOT_STAGING_FULL`; two running programs make a third `ROOT_BUSY`.
|
|
161
201
|
- A `root.run` request MAY be up to 1 MiB; the executor answers within 130
|
|
162
|
-
seconds and a client SHOULD wait 140.
|
|
202
|
+
seconds and a client SHOULD wait 140 (Timeouts).
|
|
163
203
|
- `root.run` cannot be canceled: a closed connection does not stop the
|
|
164
204
|
program, which runs until it exits or its timeout. Work that may be stopped
|
|
165
205
|
is a root job (`root.start`, `root.jobs.stop`).
|
|
@@ -250,7 +290,48 @@ use it), and `stop` otherwise; jobs are canceled with `upgrade` or `stop`
|
|
|
250
290
|
accordingly. It runs for at most 30 seconds, only while the approval is live
|
|
251
291
|
(as for the purge step), its exit and output go to the executor log, and a
|
|
252
292
|
failure does not stop the stop. `root.run` and `root.start` refuse it with
|
|
253
|
-
`POLICY_DENIED
|
|
293
|
+
`POLICY_DENIED`, so a policy whose stop or purge entry declares `run` or
|
|
294
|
+
`job` is invalid; the entry is a lifecycle step only, either
|
|
295
|
+
with neither member or as the shorthand digest. Session work takes another
|
|
296
|
+
entry, which may pin the same digest under another name.
|
|
297
|
+
|
|
298
|
+
## Package start step
|
|
299
|
+
|
|
300
|
+
Since 0.10.3. A policy MAY carry `"start": "<name>"`, naming a `root` entry
|
|
301
|
+
the executor runs once after each install or upgrade, with no session:
|
|
302
|
+
|
|
303
|
+
- The executor MUST run it at the first start of a package version (the
|
|
304
|
+
`version` of the package INFO), after the pins matched. The socket opens first
|
|
305
|
+
and the step runs once the executor has read the
|
|
306
|
+
approval tasks back; until the step ends, `status` answers `ready: false`
|
|
307
|
+
and `state` `"starting"`, and every other request is refused with
|
|
308
|
+
`EXECUTOR_STARTING` (retryable), so no session reaches the App's root work
|
|
309
|
+
while the step runs. Its
|
|
310
|
+
arguments are `install` when the executor has recorded no earlier start,
|
|
311
|
+
and `upgrade` followed by the version recorded before otherwise. Every
|
|
312
|
+
start records its version, also for a policy without the step; a package
|
|
313
|
+
that adds the step in an upgrade therefore gets `upgrade`, except on the
|
|
314
|
+
first start under an executor that predates the record, which is `install`.
|
|
315
|
+
- It runs only while the approval is live (as for the purge step); otherwise
|
|
316
|
+
it MUST log `start root step skipped: not approved` and run at the next
|
|
317
|
+
start. A step cut short because the executor ended also runs again.
|
|
318
|
+
- It runs for at most 60 seconds; its exit and output go to the executor log,
|
|
319
|
+
and the executor MUST become ready whatever it answers. A failure is the result of
|
|
320
|
+
that version: the step does not run again until the next upgrade or
|
|
321
|
+
reinstall, so the program should be idempotent.
|
|
322
|
+
- `status` answers `start_step` for such a policy: `{"state": "pending"}`
|
|
323
|
+
until the step ran for the version being served, then `state` `ok` (exit
|
|
324
|
+
`0`) or `failed`, `reason` (`install` or `upgrade`), `previous_version` for
|
|
325
|
+
an upgrade, `exit` (an exit code, `timeout`, `signal` or `refused`),
|
|
326
|
+
`output` (at most 4 KiB, which the package account can read) and
|
|
327
|
+
`finished_at` (RFC 3339).
|
|
328
|
+
- As for stop and purge, `root.run` and `root.start` refuse it with
|
|
329
|
+
`POLICY_DENIED`, and an entry that declares `run` or `job` makes the policy
|
|
330
|
+
invalid.
|
|
331
|
+
|
|
332
|
+
Because DSM's package start only writes the start request, `postinst`,
|
|
333
|
+
`postupgrade` and `start` scripts run before or while the step runs; they
|
|
334
|
+
MUST NOT expect its result. The App reads it from `status`.
|
|
254
335
|
|
|
255
336
|
## Root state directory
|
|
256
337
|
|
|
@@ -106,6 +106,14 @@
|
|
|
106
106
|
"en": "The executor is paused, for example while the package stops or upgrades.",
|
|
107
107
|
"zh-TW": "executor 已暫停,例如套件停止或升級期間。"
|
|
108
108
|
},
|
|
109
|
+
{
|
|
110
|
+
"code": "EXECUTOR_STARTING",
|
|
111
|
+
"kind": "refusal",
|
|
112
|
+
"retryable": true,
|
|
113
|
+
"httpStatus": 503,
|
|
114
|
+
"en": "The executor is running the App's start step after an install or upgrade; status answers state starting until it ends.",
|
|
115
|
+
"zh-TW": "executor 正在執行安裝或升級後的 App start 步驟;結束前 status 回報 state starting。"
|
|
116
|
+
},
|
|
109
117
|
{
|
|
110
118
|
"code": "STORAGE_ERROR",
|
|
111
119
|
"kind": "refusal",
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "Timeouts on the call chain to the executor, in seconds unless the name says ms. Each layer waits margin_s longer than the layer it calls, so the inner answer arrives first; README.md, Timeouts.",
|
|
3
|
+
"margin_s": 10,
|
|
4
|
+
"executor": {
|
|
5
|
+
"op_s": 30,
|
|
6
|
+
"root_run_program_default_s": 20,
|
|
7
|
+
"root_run_program_max_s": 120,
|
|
8
|
+
"root_run_answer_s": 130,
|
|
9
|
+
"start_step_s": 60
|
|
10
|
+
},
|
|
11
|
+
"client": {
|
|
12
|
+
"op_s": 40,
|
|
13
|
+
"root_run_s": 140
|
|
14
|
+
},
|
|
15
|
+
"request": {
|
|
16
|
+
"default_s": 60
|
|
17
|
+
},
|
|
18
|
+
"browser": {
|
|
19
|
+
"margin_ms": 2000
|
|
20
|
+
}
|
|
21
|
+
}
|