@synopackageland/templates 0.26.3 → 0.26.5

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
@@ -22,8 +22,8 @@ daemon:
22
22
  window_seconds: 300
23
23
  ```
24
24
 
25
- Templates 0.26.3 pin SDK 0.26.0, including the default controller SDK for
26
- binary/Node daemons. Use CLI 0.26.0 or later. Go Apps select
25
+ Templates 0.26.5 pin SDK 0.27.0 in native and Compose projects.
26
+ Daemon restart declarations need CLI 0.26.0 or later. Go Apps select
27
27
  their controller from their Go SDK requirement; an identity gateway selects it
28
28
  from `identity_gateway.sdk`. The CLI rejects older selected versions, even for
29
29
  an explicit `mode: off`, rather than dropping the declaration. A local SDK source
@@ -39,7 +39,7 @@ for declaration bounds, SDK selection, build/inspect checks and diagnostics.
39
39
 
40
40
  An opt-in [Shared Folder permission example](examples/shared-folder-permission/README.md)
41
41
  shows the Go status-handler registration and a Vue notice for startup checks and
42
- storage failures. It uses the same SDK 0.26.0 release pinned by the default scaffolds.
42
+ storage failures. It uses the same SDK 0.27.0 release pinned by the default scaffolds.
43
43
 
44
44
  An opt-in [native UI plus DSM console example](examples/dual-entry-console/README.md)
45
45
  shows the `console` declaration for an App that wraps a web service behind the
@@ -79,14 +79,22 @@ calls each one from the generated script of the same name (`synopkgland skill sh
79
79
  The placeholders `__PACKAGE__` (also the Go module path), `__DISPLAY_NAME__` and
80
80
  `__BACKGROUND_ENABLED__` are substituted by `init`.
81
81
 
82
- `backend/go.mod` requires `github.com/synopackageland/syno-pkg-land-sdk v0.26.0`; that line is
82
+ `backend/go.mod` requires `github.com/synopackageland/syno-pkg-land-sdk v0.27.0`; that line is
83
83
  the single source of the SDK version and `frontend/package.json` pins
84
84
  `@synopackageland/sdk` to the same version. Python and Node.js name it in
85
85
  `backend.sdk`, Rust in the `syno-pkg-land-app` tag of `backend/Cargo.toml`
86
- (and `Cargo.lock`); all of them pin 0.26.0. The Vue frontend pins
87
- `@synopackageland/ui` 0.14.7. SDK 0.26.0 accepts UI `>=0.10.1 <0.15.0`,
86
+ (and `Cargo.lock`); all of them pin 0.27.0. The Vue frontend pins
87
+ `@synopackageland/ui` 0.14.9. SDK 0.27.0 accepts UI `>=0.10.1 <0.15.0`,
88
88
  so no UI peer override is needed. Tests use jsdom 30 for UI floating-layer styles.
89
89
 
90
+ SDK 0.27.0 moves interactive NAS file operations to same-origin browser calls.
91
+ The unused server-only `bg.browse` and file-import scaffold now return
92
+ `unsupported`; custom file handlers need the SDK's
93
+ [session transport migration](https://github.com/synopackageland/syno-pkg-land-sdk/blob/v0.27.0/docs/dsm-session-transport.md).
94
+ Protected executor scaffolds need a released CLI with SDK 0.27.0 executor/lifecycle
95
+ digests; CLI 0.26.0 does not include them and refuses those builds. Rebuilt protected
96
+ executors follow normal administrator approval. No NAS acceptance is claimed.
97
+
90
98
  UI and i18n text, including the DSM glossary, omit terminal sentence periods.
91
99
  Keep punctuation between sentences and intentional loading ellipses.
92
100
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synopackageland/templates",
3
- "version": "0.26.3",
3
+ "version": "0.26.5",
4
4
  "description": "Project templates for synopkgland init: native-go, native-python, native-node and native-rust (plain or Vue, with jobs, delegate and root-ops overlays), binary and compose.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -14,7 +14,7 @@ compose:
14
14
  web: {service: web, port: 8080, health: {path: /, status: 200}}
15
15
  network: {egress: isolated}
16
16
  identity_gateway:
17
- sdk: 0.26.0
17
+ sdk: 0.27.0
18
18
  mode: none
19
19
  listen: {http: 28000}
20
20
  # Web Apps default to new-page through the shared app-launch resolver.
@@ -1,6 +1,6 @@
1
1
  Native Go package build dependencies
2
2
 
3
- github.com/synopackageland/syno-pkg-land-sdk v0.26.0 (MIT)
3
+ github.com/synopackageland/syno-pkg-land-sdk v0.27.0 (MIT)
4
4
 
5
5
  Copyright (c) 2026 synopkgland
6
6
 
@@ -4,6 +4,6 @@ go 1.25.0
4
4
 
5
5
  toolchain go1.26.10
6
6
 
7
- require github.com/synopackageland/syno-pkg-land-sdk v0.26.0
7
+ require github.com/synopackageland/syno-pkg-land-sdk v0.27.0
8
8
 
9
9
  require golang.org/x/sys v0.44.0 // indirect
@@ -1,4 +1,4 @@
1
- github.com/synopackageland/syno-pkg-land-sdk v0.26.0 h1:74lMYZURXwF2ffMRhG+T8u1XF8HsR04+NFjweRuKFw8=
2
- github.com/synopackageland/syno-pkg-land-sdk v0.26.0/go.mod h1:8GwREGbczc8mAk4Gv8FUHaukXXCUstjzkovQrNV59Cc=
1
+ github.com/synopackageland/syno-pkg-land-sdk v0.27.0 h1:DyMQUEf6mIzEW2afdfGjWh5FM1R6qM6YW2LFD7/yZeI=
2
+ github.com/synopackageland/syno-pkg-land-sdk v0.27.0/go.mod h1:8GwREGbczc8mAk4Gv8FUHaukXXCUstjzkovQrNV59Cc=
3
3
  golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
4
4
  golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
@@ -6,6 +6,7 @@ import (
6
6
  "fmt"
7
7
  "net/http"
8
8
  "net/http/httptest"
9
+ "os"
9
10
  "path/filepath"
10
11
  "strings"
11
12
  "testing"
@@ -136,12 +137,14 @@ func TestBackgroundStatusReportsLimitsAndWorker(t *testing.T) {
136
137
  if limits["maxInputBytes"].(float64) != 512*1024 || limits["maxQueued"].(float64) != 16 || limits["maxTotalBytes"].(float64) != 16<<20 || limits["jobTimeoutSeconds"].(float64) != 60 {
137
138
  t.Fatalf("limits: %v", limits)
138
139
  }
139
- if err := e.store.Heartbeat(context.Background(), background.WorkerInfo{PID: 9, UID: 255853, Username: "pkg"}); err != nil {
140
+ info := background.WorkerInfo{PID: os.Getpid(), UID: os.Getuid(), Username: "pkg"}
141
+ if err := e.store.Heartbeat(context.Background(), info); err != nil {
140
142
  t.Fatal(err)
141
143
  }
144
+ t.Cleanup(func() { e.store.ClearHeartbeat(info) })
142
145
  _, out = e.call(alice, "bg.status", `{}`)
143
146
  w := data(out)["worker"].(map[string]any)
144
- if w["alive"] != true || w["uid"].(float64) != 255853 {
147
+ if w["alive"] != true || w["uid"].(float64) != float64(info.UID) || w["pid"].(float64) != float64(info.PID) {
145
148
  t.Fatalf("worker: %v", w)
146
149
  }
147
150
  }
@@ -38,22 +38,34 @@ test('the capability surface uses an explicit long-running facade without legacy
38
38
  test('the default surface binds the real routes and the session-only picker',async()=>{
39
39
  const grant={id:'g1',key:'save',path:'/home',username:'alice',lifetime:'until-revoked'}
40
40
  let selected=false
41
+ const fetch=vi.fn(async(url:string,init?:RequestInit)=>{
42
+ expect(url).toBe('/webapi/entry.cgi')
43
+ const body=init?.body as URLSearchParams
44
+ expect(body.get('api')).toBe('SYNO.FileStation.List')
45
+ expect(body.get('method')).toBe('list_share')
46
+ expect(body.get('SynoToken')).toBe('fixture-token')
47
+ expect(init?.credentials).toBe('same-origin')
48
+ return new Response(JSON.stringify({success:true,data:{shares:[{name:'home',path:'/home',isdir:true}],offset:0,total:1}}))
49
+ })
50
+ vi.stubGlobal('fetch',fetch);cleanup.push(()=>vi.unstubAllGlobals())
41
51
  const call=vi.fn(async(method:string,params?:unknown)=>{
52
+ if(method==='nas.session.status')return {mode:'browser-session'}
42
53
  if(method==='delegate.status')return {state:'ready',disabled:false,lifetime:'until-revoked',destinations:['save']}
43
54
  if(method==='delegate.destination')return {key:'save',selection:{scope:'home',root:'/home',generation:0},destination:selected?grant:null,status:selected?'active':'missing'}
44
55
  if(method==='delegate.list')return {delegations:selected?[{delegation_id:'g1',destination:'save',path:'/home',subject:{username:'alice'},lifetime:'until-revoked',revoked:false}]:[]}
45
56
  if(method==='delegate.operations.list')return {operations:[]}
46
- if(method==='bg.browse')return {shares:[{name:'home',path:'/home',isdir:true}],offset:0,total:1}
47
57
  if(method==='delegate.select_destination'){selected=true;return grant}
48
58
  if(method==='delegate.example.export')return {delegation_id:'g1',job_id:(params as {job_id:string}).job_id}
49
59
  throw {code:'unexpected'}
50
60
  })
51
- const root=render({call,locale:'en'});await settle()
61
+ const root=render({call,locale:'en',files:{token:()=> 'fixture-token'}});await settle()
52
62
  button(root,'Choose folder').click();await settle()
53
63
  // The SDK picker selects a folder with a row click.
54
64
  const row=root.querySelector<HTMLElement>('tr[data-row-key="/home"]')!;expect(row).toBeTruthy();row.dispatchEvent(new MouseEvent('click',{bubbles:true}));await settle()
55
65
  button(root,'Confirm selection').click();await settle()
56
66
  expect(call).toHaveBeenCalledWith('delegate.select_destination',{key:'save',path:'/home'})
67
+ expect(fetch).toHaveBeenCalledTimes(1)
68
+ expect(call).not.toHaveBeenCalledWith('bg.browse',expect.anything())
57
69
  // The SDK hides the sample save unless an App opts in; the template opts in with sample-save.
58
70
  button(root,'Save example file').click();await settle()
59
71
  expect(call).toHaveBeenCalledWith('delegate.example.export',expect.objectContaining({key:'save'}))
@@ -16,7 +16,7 @@ import (
16
16
 
17
17
  func init() {
18
18
  // The generic route tests need valid params for every background route.
19
- // The fixture has no DSM cookie; import is refused before reading a file.
19
+ // The SDK refuses retired backend session relays before reading a file.
20
20
  // No jobs or schedules exist in its fresh data directory.
21
21
  const id = `{"id":"missing"}`
22
22
  sampleParams["bg.jobs.purge"] = `{"owner":{"user":"missing","uid":"9999"}}`
@@ -38,8 +38,8 @@ func init() {
38
38
  sampleParams["bg.jobs.pause"] = id
39
39
  sampleParams["bg.jobs.resume"] = id
40
40
  sampleParams["bg.jobs.result"] = id
41
- sampleOutcome["bg.browse"] = "session_required"
42
- sampleOutcome["bg.jobs.submit"] = "session_required"
41
+ sampleOutcome["bg.browse"] = "unsupported"
42
+ sampleOutcome["bg.jobs.submit"] = "unsupported"
43
43
  sampleOutcome["bg.jobs.get"] = "not_found"
44
44
  sampleOutcome["bg.jobs.cancel"] = "not_found"
45
45
  sampleOutcome["bg.jobs.pause"] = "not_found"
@@ -7,8 +7,8 @@
7
7
  "name": "native-dsm-vue-app",
8
8
  "dependencies": {
9
9
  "@lucide/vue": "1.48.0",
10
- "@synopackageland/sdk": "0.26.0",
11
- "@synopackageland/ui": "0.14.7",
10
+ "@synopackageland/sdk": "0.27.0",
11
+ "@synopackageland/ui": "0.14.9",
12
12
  "vue": "3.5.43"
13
13
  },
14
14
  "devDependencies": {
@@ -1152,9 +1152,9 @@
1152
1152
  }
1153
1153
  },
1154
1154
  "node_modules/@synopackageland/sdk": {
1155
- "version": "0.26.0",
1156
- "resolved": "https://registry.npmjs.org/@synopackageland/sdk/-/sdk-0.26.0.tgz",
1157
- "integrity": "sha512-f6nKQzA+Bn+ilHAtJdoksPg/t3beA0Nxo1tOvFrTIqSuzB8CeMCQ5zZ263NigFvV3yDYwM9T4AD4C0Iw/LXf5Q==",
1155
+ "version": "0.27.0",
1156
+ "resolved": "https://registry.npmjs.org/@synopackageland/sdk/-/sdk-0.27.0.tgz",
1157
+ "integrity": "sha512-KIFeYhzmiH0QFAD8SutTvSXCiynx/D84ydOROGPS9B5VcHkLU8uqtD9Mwac9G0UY7mPITioGJuJGXpGytFPCVg==",
1158
1158
  "license": "MIT",
1159
1159
  "peerDependencies": {
1160
1160
  "@lucide/vue": "^1.48.0",
@@ -1171,9 +1171,9 @@
1171
1171
  }
1172
1172
  },
1173
1173
  "node_modules/@synopackageland/ui": {
1174
- "version": "0.14.7",
1175
- "resolved": "https://registry.npmjs.org/@synopackageland/ui/-/ui-0.14.7.tgz",
1176
- "integrity": "sha512-QbqAQcE4S9LWW00kbyJZbkBgF0GGo9blRYseae+lvCDvYghjLm3inoGmHZbQPMYaSZx8YdPfNwpkYQdSxdAIyQ==",
1174
+ "version": "0.14.9",
1175
+ "resolved": "https://registry.npmjs.org/@synopackageland/ui/-/ui-0.14.9.tgz",
1176
+ "integrity": "sha512-Vr925mORKVuWJH/EaEvaSUF4nxsHP0SWUYwwMjM009MFw+UHaABoEtasAliCDsnI7CnlggLcexO3ad5slm9IVw==",
1177
1177
  "license": "MIT",
1178
1178
  "dependencies": {
1179
1179
  "@internationalized/date": "3.12.4",
@@ -8,8 +8,8 @@
8
8
  },
9
9
  "dependencies": {
10
10
  "@lucide/vue": "1.48.0",
11
- "@synopackageland/sdk": "0.26.0",
12
- "@synopackageland/ui": "0.14.7",
11
+ "@synopackageland/sdk": "0.27.0",
12
+ "@synopackageland/ui": "0.14.9",
13
13
  "vue": "3.5.43"
14
14
  },
15
15
  "devDependencies": {
@@ -49,7 +49,7 @@ backend:
49
49
  runtime: node
50
50
  dir: backend/app
51
51
  entry: main.js
52
- sdk: 0.26.0
52
+ sdk: 0.27.0
53
53
  node: { package: Node.js_v22 }
54
54
 
55
55
  ui:
@@ -47,7 +47,7 @@ backend:
47
47
  runtime: python
48
48
  dir: backend/app
49
49
  entry: main.py
50
- sdk: 0.26.0
50
+ sdk: 0.27.0
51
51
 
52
52
  ui:
53
53
  # Non-UI-SDK frontends open a full page; Portal is a separate opt-in.
@@ -104,8 +104,8 @@ dependencies = [
104
104
 
105
105
  [[package]]
106
106
  name = "syno-pkg-land-app"
107
- version = "0.26.0"
108
- source = "git+https://github.com/synopackageland/syno-pkg-land-sdk?tag=v0.26.0#ff3b079cf034e12ce69e936e4fefb010cd010b3d"
107
+ version = "0.27.0"
108
+ source = "git+https://github.com/synopackageland/syno-pkg-land-sdk?tag=v0.27.0#a10253ad1c94b647f4b626d9b99591b5dc2571a1"
109
109
  dependencies = [
110
110
  "libc",
111
111
  "serde",
@@ -9,7 +9,7 @@ libc = "0.2"
9
9
  serde = { version = "1", features = ["derive"] }
10
10
  serde_json = "1"
11
11
  # The SDK version is the tag; `synopkgland check` reads it from Cargo.lock.
12
- syno-pkg-land-app = { git = "https://github.com/synopackageland/syno-pkg-land-sdk", tag = "v0.26.0" }
12
+ syno-pkg-land-app = { git = "https://github.com/synopackageland/syno-pkg-land-sdk", tag = "v0.27.0" }
13
13
 
14
14
  [profile.release]
15
15
  # A handler panic becomes an "internal" reply; abort would end the App without one.