@synopackageland/sdk 0.50.0 → 0.50.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.
@@ -1,4 +1,5 @@
1
1
  import { type CallOptions } from './context';
2
+ import type { createDsmSession } from './dsm/session.js';
2
3
  export interface BatchCall {
3
4
  method: string;
4
5
  params?: Record<string, unknown>;
@@ -14,12 +15,23 @@ export type BatchResult<T = unknown> = {
14
15
  };
15
16
  };
16
17
  export type Batch = <T = unknown>(calls: readonly BatchCall[], options?: CallOptions) => Promise<BatchResult<T>[]>;
18
+ /** Trusted App metadata, never inferred from method names or request params.
19
+ * Copy effect from the operation registry; classify AI and streaming explicitly. */
20
+ export interface SessionRetryOperation {
21
+ effect: 'read' | 'write' | 'destructive';
22
+ kind: 'rpc' | 'ai' | 'stream';
23
+ }
24
+ export interface SessionRetryOptions {
25
+ session: ReturnType<typeof createDsmSession>;
26
+ operations: Readonly<Record<string, SessionRetryOperation>>;
27
+ }
17
28
  export interface ClientOptions {
18
29
  endpoint: string;
19
30
  token?: () => string | undefined;
20
31
  ready?: () => Promise<unknown>;
21
32
  fetch?: typeof globalThis.fetch;
22
33
  requestTimeout?: number;
34
+ sessionRetry?: SessionRetryOptions;
23
35
  }
24
36
  /** A same-origin JSON client. Batch results stay independent and ordered. */
25
37
  export declare function createClient(options: ClientOptions): {
@@ -0,0 +1,6 @@
1
+ import type { Context } from '../context';
2
+ /** Optional link for an App's https_required page. PortInfo is administrator
3
+ * only: unknown and ordinary subjects never start discovery. The result opens
4
+ * DSM, not an App route; no query, fragment or credentials are carried across.
5
+ * No result means show instructions, never guess a configured port. */
6
+ export declare function readDsmHttpsURL(ctx: Pick<Context, 'user' | 'files' | 'webApi' | 'requestTimeout'>, pageURL: string, signal?: AbortSignal): Promise<string | undefined>;
@@ -3,7 +3,7 @@
3
3
  * This plain JavaScript factory is also embedded by the CLI into DSM's
4
4
  * generated window, so Go-only Apps need no frontend build toolchain.
5
5
  * @param {{read: () => string | undefined, write?: (token: string) => void, fetch: typeof globalThis.fetch}} options
6
- * @returns {{token: () => string | undefined, ready: () => Promise<string | undefined>}}
6
+ * @returns {{token: () => string | undefined, ready: () => Promise<string | undefined>, refresh: (rejected?: string) => Promise<string | undefined>}}
7
7
  */
8
8
  export function createDsmSession(options: {
9
9
  read: () => string | undefined;
@@ -12,4 +12,5 @@ export function createDsmSession(options: {
12
12
  }): {
13
13
  token: () => string | undefined;
14
14
  ready: () => Promise<string | undefined>;
15
+ refresh: (rejected?: string) => Promise<string | undefined>;
15
16
  };
@@ -38,5 +38,6 @@ export * from './protocol/v1';
38
38
  export { encodeRequest, decodeResponse, type ProtocolAuth, type ProtocolResponse } from './protocol/codec';
39
39
  export { appDenial, appRefusal, type AppDenial } from './authorization/refusal';
40
40
  export { createEntryCheck, type EntryCheck, type EntryFailure, type EntryMode } from './entry/check';
41
- export { createClient, type Batch, type BatchCall, type BatchResult, type ClientOptions } from './client';
41
+ export { createClient, type Batch, type BatchCall, type BatchResult, type ClientOptions, type SessionRetryOptions, type SessionRetryOperation } from './client';
42
42
  export { readDsmPorts, type DsmPort, type DsmPortRange } from './dsm/service-ports';
43
+ export { readDsmHttpsURL } from './dsm/https';
package/dist/vue.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { D as dt, i as Ba } from "./context-DWEbBTIr.js";
2
2
  import { c as So } from "./context-DWEbBTIr.js";
3
3
  import { appRefusal as va, appDenial as He, delegateCopy as Ue, createDsmFileStation as ct, appLifecycle as Pe, lifecycleRetryDelay as Ca, joinSentences as Oa, lifecycleCopy as Fe, shellCopy as oa, uiLocale as Fa, format as Ge, nasCopy as Ve, nasErrorCopy as qa, saveCopy as $a, saveError as ia, createNasProvider as Ma, labelSeparator as Sa, identityCopy as Ka, backgroundCopy as vt, createBackgroundPickerProvider as ft, backgroundErrorCopy as pt, requestKey as _a, lifecycleRefusal as mt, errorCopy as yt, scopedPicker as bt, authorizationCopy as Ha, createEntryCheck as gt } from "./index.js";
4
- import { FILE_STATION_APP as Po, LIFECYCLE_RETRY_MAX_MS as To, LIFECYCLE_STARTING_RETRY_MAX_MS as Ao, MAX_LAUNCH_ROUTE as zo, activePage as Ro, authorizationCatalogs as Io, backgroundCatalogs as Uo, bridgeCatalogs as Do, bridgeErrorCopy as Lo, catalogs as No, createBackgroundSaveFacade as Vo, createClient as Bo, createDsmSession as Oo, createFileTransfers as Fo, createPortalAccess as qo, createSharedFolderAccess as Mo, createSharedFolderPermission as Ko, createStandaloneContext as Ho, createStandaloneHost as Xo, decodeResponse as Go, delegateCatalogs as Wo, dsmLaunchURL as Jo, encodeRequest as Yo, fileStationPath as Qo, followLaunchRoute as Zo, identityCatalogs as jo, launchRoute as ei, mergeCatalogs as ai, nasCatalogs as ti, openFileInFileStation as li, openFolderInFileStation as ni, portalCatalogs as si, portalMessages as oi, protocolCodes as ii, protocolOps as ui, protocolSchemas as ri, readDsmPorts as di, saveCatalogs as ci, sharedFolderAccessFor as vi, sharedFolderCatalogs as fi, sharedFolderMessages as pi, sharedFolderPermissionMessage as mi, shellCatalogs as yi, shellPages as bi, uiLocales as gi } from "./index.js";
4
+ import { FILE_STATION_APP as Po, LIFECYCLE_RETRY_MAX_MS as To, LIFECYCLE_STARTING_RETRY_MAX_MS as Ao, MAX_LAUNCH_ROUTE as zo, activePage as Ro, authorizationCatalogs as Io, backgroundCatalogs as Uo, bridgeCatalogs as Do, bridgeErrorCopy as Lo, catalogs as No, createBackgroundSaveFacade as Vo, createClient as Bo, createDsmSession as Oo, createFileTransfers as Fo, createPortalAccess as qo, createSharedFolderAccess as Mo, createSharedFolderPermission as Ko, createStandaloneContext as Ho, createStandaloneHost as Xo, decodeResponse as Go, delegateCatalogs as Wo, dsmLaunchURL as Jo, encodeRequest as Yo, fileStationPath as Qo, followLaunchRoute as Zo, identityCatalogs as jo, launchRoute as ei, mergeCatalogs as ai, nasCatalogs as ti, openFileInFileStation as li, openFolderInFileStation as ni, portalCatalogs as si, portalMessages as oi, protocolCodes as ii, protocolOps as ui, protocolSchemas as ri, readDsmHttpsURL as di, readDsmPorts as ci, saveCatalogs as vi, sharedFolderAccessFor as fi, sharedFolderCatalogs as pi, sharedFolderMessages as mi, sharedFolderPermissionMessage as yi, shellCatalogs as bi, shellPages as gi, uiLocales as hi } from "./index.js";
5
5
  import { inject as ze, ref as y, computed as x, onBeforeUnmount as ke, Comment as ht, Text as kt, Fragment as ee, watch as We, onMounted as xe, defineComponent as ve, openBlock as n, createElementBlock as w, createElementVNode as $, toDisplayString as o, createCommentVNode as b, renderList as me, normalizeClass as Re, createVNode as p, unref as e, createTextVNode as h, createBlock as g, renderSlot as ge, withCtx as s, resolveDynamicComponent as je, normalizeProps as ua, mergeProps as Ea, withModifiers as Je, isRef as ra, provide as Xe, useTemplateRef as Ne, watchEffect as la, useSlots as Xa, guardReactiveProps as za, createSlots as fa, Teleport as Ga, markRaw as _t, h as wt, useId as xt, shallowRef as Ct, onUnmounted as Wa, nextTick as $t } from "vue";
6
6
  import { Timer as St, Info as Et, ShieldCheck as Ja, ChevronRight as Ya, LogOut as Pt, ChevronLeft as Tt, RotateCw as At } from "@lucide/vue";
7
7
  import { SettingsSection as we, Callout as j, Button as N, SettingsRow as $e, Skeleton as Be, Badge as ea, PathDisplay as Oe, Form as Ye, FormItem as Te, Select as Pa, Input as Ie, Dialog as qe, ensureDeviceViewport as zt, AppRoot as Rt, ConfigProvider as It, PageContent as Ra, PageHeader as Ia, AppLayout as Ut, LoadingArea as Qa, AppSidebar as Dt, AppSidebarUser as Lt, IconButton as sa, AppToolbar as Nt, InfoTip as Za, FileTypeIcon as ha, Breadcrumb as Vt, FilePicker as Bt, TreeView as Ot, DataGrid as Ft, Link as wa, FormActions as pa, Card as Ua, Checkbox as qt, ListItem as Da } from "@synopackageland/ui";
@@ -4359,21 +4359,22 @@ export {
4359
4359
  ii as protocolCodes,
4360
4360
  ui as protocolOps,
4361
4361
  ri as protocolSchemas,
4362
- di as readDsmPorts,
4362
+ di as readDsmHttpsURL,
4363
+ ci as readDsmPorts,
4363
4364
  _a as requestKey,
4364
- ci as saveCatalogs,
4365
+ vi as saveCatalogs,
4365
4366
  $a as saveCopy,
4366
4367
  ia as saveError,
4367
4368
  bt as scopedPicker,
4368
- vi as sharedFolderAccessFor,
4369
- fi as sharedFolderCatalogs,
4370
- pi as sharedFolderMessages,
4371
- mi as sharedFolderPermissionMessage,
4372
- yi as shellCatalogs,
4369
+ fi as sharedFolderAccessFor,
4370
+ pi as sharedFolderCatalogs,
4371
+ mi as sharedFolderMessages,
4372
+ yi as sharedFolderPermissionMessage,
4373
+ bi as shellCatalogs,
4373
4374
  oa as shellCopy,
4374
- bi as shellPages,
4375
+ gi as shellPages,
4375
4376
  Fa as uiLocale,
4376
- gi as uiLocales,
4377
+ hi as uiLocales,
4377
4378
  Gs as useAuthorization,
4378
4379
  Mt as useExecutorPreload,
4379
4380
  et as useExecutorSetup,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "formatVersion": 1,
3
- "sdkVersion": "0.50.0",
3
+ "sdkVersion": "0.50.1",
4
4
  "executorVersion": "0.49.5",
5
5
  "executorDigests": {
6
6
  "x86_64": "1a2dbb1c93a5d7cf5c4d5cafd2526c152e1cc21611649875db8e1c23837c2874",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synopackageland/sdk",
3
- "version": "0.50.0",
3
+ "version": "0.50.1",
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",
@@ -1,6 +1,6 @@
1
1
  # Executor protocol v1
2
2
 
3
- Since 0.9.0. The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD,
3
+ The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD,
4
4
  SHOULD NOT, RECOMMENDED, MAY and OPTIONAL are to be interpreted as described in
5
5
  RFC 2119.
6
6
 
@@ -30,7 +30,7 @@ the executor against the vectors here.
30
30
 
31
31
  ## Timeouts
32
32
 
33
- Since 0.10.3. Every layer between the browser and a root program waits
33
+ Every layer between the browser and a root program waits
34
34
  longer than the layer it calls, so the inner answer, or the inner refusal,
35
35
  arrives before the outer layer gives up. The margin is 10 seconds between
36
36
  the executor and its client and between the client and the request; the
@@ -61,13 +61,13 @@ reasons are recorded in `scripts/timeout-allowlist.json`.
61
61
  - `op` MUST be one of the ops with a schema in `schema/`. An unknown op is
62
62
  `UNKNOWN_OP`; an op outside the approved policy is `POLICY_DENIED`.
63
63
  - `auth` is OPTIONAL. When present it MUST contain only `dsm_cookie`,
64
- `dsm_synotoken` and `remote_addr` (since 0.9.4), the browser's address
64
+ `dsm_synotoken` and `remote_addr`, the browser's address
65
65
  (REMOTE_ADDR). DSM's Application Privileges are evaluated for that address;
66
66
  an op that checks them MUST be refused with `APP_DENIED` when a present
67
67
  `auth` has no usable `remote_addr`. A grant records the `remote_addr` of the
68
68
  `delegate.create` that made it (creating it again records the new one), and
69
- an operation records the address of its `files.moveFromStaging` (since
70
- 0.9.6). A request without `auth` under a grant, and the operation's
69
+ an operation records the address of its `files.moveFromStaging`. A request
70
+ without `auth` under a grant, and the operation's
71
71
  background revalidation, are checked from that recorded address; work with no
72
72
  recorded address is checked as coming from 127.0.0.1. A present `auth` is
73
73
  always treated as caller authentication, never ignored, even when empty. Ops whose schema says
@@ -112,7 +112,7 @@ reasons are recorded in `scripts/timeout-allowlist.json`.
112
112
  ## Status
113
113
 
114
114
  `status` answers `version` (`"1"`), `ready`, `disabled`, `executor_digest`
115
- and `policy_digest`. With `auth` (since 0.9.6) it also answers `allowed`:
115
+ and `policy_digest`. With `auth` it also answers `allowed`:
116
116
  whether DSM's Application Privileges let the caller use the App and File
117
117
  Station from `remote_addr`, the check `delegate.create` makes; an invalid
118
118
  session is `AUTH_DENIED`. A CGI sends the caller's `auth` so an App the
@@ -136,7 +136,7 @@ the tasks back itself.
136
136
 
137
137
  ## Application Portal
138
138
 
139
- Since 0.9.6. A policy MAY carry `"portal": {"application": "<display name>",
139
+ A policy MAY carry `"portal": {"application": "<display name>",
140
140
  "alias": "<default alias>"}` together with both `portal.register` and
141
141
  `portal.unregister`; a policy with only some of the three is invalid. The
142
142
  executor then registers the App's Application Portal entry the way DSM's
@@ -169,7 +169,7 @@ packages.
169
169
 
170
170
  ## Root programs
171
171
 
172
- Since 0.10.0. Each `root` entry pins a program by its SHA-256 digest; a bare
172
+ Each `root` entry pins a program by its SHA-256 digest; a bare
173
173
  digest is a script `root.run` may run with the defaults. The object form is
174
174
  `{"digest", "kind", "schema", "run"}`: `kind` `script` (`root/<name>.sh`) or
175
175
  `binary` (`root/<name>`), `schema` a closed JSON Schema subset for its params,
@@ -223,7 +223,7 @@ Every root program, whatever starts it:
223
223
 
224
224
  ## Root jobs
225
225
 
226
- Since 0.10.0. `root.start`, `root.jobs.list`, `root.jobs.get` and
226
+ `root.start`, `root.jobs.list`, `root.jobs.get` and
227
227
  `root.jobs.stop` come together in `operations`. Each requires an administrator
228
228
  session whose Application Privileges allow the App, like `root.run`; any such
229
229
  administrator sees and stops every job of the package.
@@ -299,7 +299,7 @@ The job reports on fd 5 and is told to stop on fd 4; both are pipes.
299
299
 
300
300
  ## Package stop step
301
301
 
302
- Since 0.10.0. A policy MAY carry `"stop": "<name>"`, naming a `root` entry the
302
+ A policy MAY carry `"stop": "<name>"`, naming a `root` entry the
303
303
  executor runs when the package stops, after its jobs ended, with no session.
304
304
  Its argument is `prepare-upgrade` when the package account wrote `upgrade`
305
305
  to `var/executor/stop-reason` before the stop request (the
@@ -315,7 +315,7 @@ entry, which may pin the same digest under another name.
315
315
 
316
316
  ## Package start step
317
317
 
318
- Since 0.10.3. A policy MAY carry `"start": "<name>"`, naming a `root` entry
318
+ A policy MAY carry `"start": "<name>"`, naming a `root` entry
319
319
  the executor runs once after each install or upgrade, with no session:
320
320
 
321
321
  - The executor MUST run it at the first start of a package version (the
@@ -353,7 +353,7 @@ MUST NOT expect its result. The App reads it from `status`.
353
353
 
354
354
  ## Root state directory
355
355
 
356
- Since 0.10.0. A policy with `"root_state": true` gives its root programs a
356
+ A policy with `"root_state": true` gives its root programs a
357
357
  directory only root can read: `/volumeN/@synopkgland/<package>`, root:root
358
358
  0700, on the volume that holds the package's `var` (DSM's
359
359
  `/volumeN/@appdata/<package>`); `/volumeN/@synopkgland` is root:root 0755.
@@ -366,7 +366,7 @@ the step the executor deletes it for `delete-state` and keeps it for
366
366
 
367
367
  ## Uninstall purge step
368
368
 
369
- Since 0.9.7. A policy MAY carry `"purge": "<name>"`, naming one of its `root`
369
+ A policy MAY carry `"purge": "<name>"`, naming one of its `root`
370
370
  ops as the App's root step at uninstall; any other value makes the policy
371
371
  invalid. Approving that policy is the administrator's consent that the op
372
372
  runs as root at uninstall, with no session.
@@ -398,8 +398,8 @@ runs as root at uninstall, with no session.
398
398
  Application Privileges, scope, directory identity and write permission
399
399
  against DSM. A failure the user or an administrator can undo MUST fail only
400
400
  that operation and MUST keep the grant: `PERMISSION_DENIED` (the ACL refuses
401
- the write), `not-found` (the granted folder is not at its path) and, since
402
- 0.9.6, `APP_DENIED` (an Application Privileges rule refuses the account from
401
+ the write), `not-found` (the granted folder is not at its path) and
402
+ `APP_DENIED` (an Application Privileges rule refuses the account from
403
403
  the checked address). Once the cause is fixed, a new operation under the same
404
404
  grant succeeds. Any other revalidation failure (`DELEGATION_DENIED`,
405
405
  `INELIGIBLE`, `SCOPE_DENIED`, including a different folder at the granted
@@ -448,7 +448,7 @@ administrator). Their `dsm_cookie` is the user name and `dsm_synotoken` is
448
448
  New ops and members are added with a `since` of the SDK release. The protocol
449
449
  `v` changes only for an incompatible envelope change.
450
450
 
451
- ## JSON WebAPI grants (since 0.11.0)
451
+ ## JSON WebAPI grants
452
452
 
453
453
  `webapi.call` MUST execute only an exact API/method/version in the grant's named
454
454
  `webapi` policy profile, with `runner` fixed to its owner. A profile has `purpose`
@@ -475,7 +475,7 @@ cannot be confirmed MUST answer `WEBAPI_UNCERTAIN` (nonretryable); client
475
475
  transport failure MAY also hide a completed operation. Binary/streaming replies
476
476
  MUST be refused. These bounds and semantics also apply to until-revoked grants.
477
477
 
478
- ## Raw WebAPI extension (since 0.12.1)
478
+ ## Raw WebAPI extension
479
479
 
480
480
  The JSON-only restriction above applies to the default response mode. An explicit
481
481
  `response_type:"raw"` MUST require a positive, approved profile `raw_max_bytes`