@synopackageland/cli 0.6.1 → 0.7.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.
Files changed (578) hide show
  1. package/CHANGELOG.md +613 -0
  2. package/README.md +81 -89
  3. package/dist/add.js +39 -16
  4. package/dist/build-spk/delegate-scope.d.ts +6 -0
  5. package/dist/build-spk/delegate-scope.js +34 -0
  6. package/dist/build-spk/dsm-arch.d.ts +7 -1
  7. package/dist/build-spk/dsm-arch.js +24 -28
  8. package/dist/build-spk/dsm-platforms.json +39 -0
  9. package/dist/build-spk/dsm-version.d.ts +11 -0
  10. package/dist/build-spk/dsm-version.js +17 -0
  11. package/dist/build-spk/gateway.d.ts +1 -1
  12. package/dist/build-spk/gateway.js +2 -2
  13. package/dist/build-spk/generator.js +30 -5
  14. package/dist/build-spk/notices.js +4 -1
  15. package/dist/build-spk/resource-worker.js +3 -0
  16. package/dist/build-spk/wizard-messages.d.ts +66 -0
  17. package/dist/build-spk/wizard-messages.js +75 -9
  18. package/dist/cli.js +15 -7
  19. package/dist/contract/schema-validate.js +8 -0
  20. package/dist/contract/validate.js +30 -0
  21. package/dist/deploy/deploy.d.ts +1 -1
  22. package/dist/deploy/deploy.js +8 -0
  23. package/dist/deploy/plan.js +1 -1
  24. package/dist/deploy/spk-version.js +1 -1
  25. package/dist/error-registry.js +43 -15
  26. package/dist/host/dsm-client.d.ts +8 -4
  27. package/dist/host/dsm-client.js +10 -4
  28. package/dist/host/types.d.ts +2 -1
  29. package/dist/info.js +18 -2
  30. package/dist/init.d.ts +3 -0
  31. package/dist/init.js +49 -18
  32. package/dist/package-metadata.d.ts +21 -0
  33. package/dist/package-metadata.js +101 -0
  34. package/dist/portal/alias.d.ts +25 -0
  35. package/dist/portal/alias.js +48 -0
  36. package/dist/portal/package.d.ts +33 -0
  37. package/dist/portal/package.js +116 -0
  38. package/dist/runtime/delegate-contract.d.ts +79 -0
  39. package/dist/runtime/delegate-contract.js +27 -0
  40. package/dist/runtime/executor-build.d.ts +1 -1
  41. package/dist/runtime/executor-build.js +5 -4
  42. package/dist/runtime/executor-inspect.d.ts +3 -0
  43. package/dist/runtime/executor-inspect.js +11 -5
  44. package/dist/runtime/executor-policy.d.ts +12 -0
  45. package/dist/runtime/executor-policy.js +43 -3
  46. package/dist/runtime/executor-scope-task.d.ts +4 -0
  47. package/dist/runtime/executor-scope-task.js +21 -0
  48. package/dist/runtime/executor-tasks.d.ts +2 -1
  49. package/dist/runtime/executor-tasks.js +4 -4
  50. package/dist/skill.js +1 -0
  51. package/dist/standalone/api-permissions.d.ts +10 -0
  52. package/dist/standalone/api-permissions.js +19 -2
  53. package/dist/standalone/background.d.ts +16 -0
  54. package/dist/standalone/background.js +69 -2
  55. package/dist/standalone/binary.d.ts +1 -1
  56. package/dist/standalone/binary.js +22 -8
  57. package/dist/standalone/build.d.ts +1 -1
  58. package/dist/standalone/build.js +38 -8
  59. package/dist/standalone/daemon.d.ts +1 -1
  60. package/dist/standalone/daemon.js +2 -1
  61. package/dist/standalone/dsm-window.d.ts +3 -1
  62. package/dist/standalone/dsm-window.js +72 -15
  63. package/dist/standalone/inspect-spk.d.ts +8 -0
  64. package/dist/standalone/inspect-spk.js +105 -26
  65. package/dist/standalone/lifecycle.js +86 -8
  66. package/dist/standalone/manifest.d.ts +13 -0
  67. package/dist/standalone/manifest.js +57 -8
  68. package/dist/standalone/native-authorization-window.d.ts +1 -1
  69. package/dist/standalone/native-authorization-window.js +2 -0
  70. package/dist/standalone/native-layout.d.ts +3 -0
  71. package/dist/standalone/native-layout.js +37 -5
  72. package/dist/standalone/portal-window.d.ts +21 -0
  73. package/dist/standalone/portal-window.js +155 -0
  74. package/dist/standalone/portal.d.ts +4 -0
  75. package/dist/standalone/portal.js +4 -0
  76. package/dist/standalone/resource.d.ts +5 -3
  77. package/dist/standalone/resource.js +6 -3
  78. package/dist/standalone/root-window.js +62 -15
  79. package/dist/standalone/spk.d.ts +1 -1
  80. package/dist/standalone/spk.js +25 -7
  81. package/dist/templates/_daemon/main_test.go +61 -8
  82. package/dist/templates/_executor/README.md +127 -16
  83. package/dist/templates/_executor/anchor.go +146 -0
  84. package/dist/templates/_executor/anchor_test.go +126 -0
  85. package/dist/templates/_executor/apppriv_review_test.go +1 -1
  86. package/dist/templates/_executor/cancel_contract_test.go +236 -0
  87. package/dist/templates/_executor/copy.go +64 -0
  88. package/dist/templates/_executor/copy_test.go +88 -0
  89. package/dist/templates/_executor/dsm.go +23 -10
  90. package/dist/templates/_executor/dsm_test.go +95 -1
  91. package/dist/templates/_executor/executor.go +260 -49
  92. package/dist/templates/_executor/executor_test.go +36 -6
  93. package/dist/templates/_executor/identity.go +27 -1
  94. package/dist/templates/_executor/identity_kernel_linux_test.go +60 -0
  95. package/dist/templates/_executor/identity_linux.go +82 -0
  96. package/dist/templates/_executor/identity_security_test.go +43 -0
  97. package/dist/templates/_executor/internal/lifecycle/lifecycle.go +5 -0
  98. package/dist/templates/_executor/internal/lifecycle/lifecycle_test.go +61 -3
  99. package/dist/templates/_executor/internal/taskscript/boot.sh +9 -9
  100. package/dist/templates/_executor/internal/taskscript/cmd/main.go +2 -2
  101. package/dist/templates/_executor/internal/taskscript/control.sh +15 -10
  102. package/dist/templates/_executor/internal/taskscript/tasks.go +5 -3
  103. package/dist/templates/_executor/lifecycle_test.go +11 -0
  104. package/dist/templates/_executor/link_linux.go +28 -0
  105. package/dist/templates/_executor/long_running_test.go +530 -0
  106. package/dist/templates/_executor/main.go +72 -20
  107. package/dist/templates/_executor/move_linux.go +490 -0
  108. package/dist/templates/_executor/move_linux_test.go +460 -0
  109. package/dist/templates/_executor/move_validation.go +46 -0
  110. package/dist/templates/_executor/move_validation_test.go +187 -0
  111. package/dist/templates/_executor/operations.go +926 -0
  112. package/dist/templates/_executor/platform_linux.go +24 -173
  113. package/dist/templates/_executor/platform_linux_test.go +9 -65
  114. package/dist/templates/_executor/platform_other.go +30 -4
  115. package/dist/templates/_executor/process.go +3 -0
  116. package/dist/templates/_executor/records.go +242 -0
  117. package/dist/templates/_executor/scope_cancel_contract_test.go +91 -0
  118. package/dist/templates/_executor/scope_client.go +37 -0
  119. package/dist/templates/_executor/scope_contract.go +12 -0
  120. package/dist/templates/_executor/selected_scope.go +146 -0
  121. package/dist/templates/_executor/selected_scope_test.go +186 -0
  122. package/dist/templates/_executor/status_disabled_test.go +33 -0
  123. package/dist/templates/_executor/store.go +4 -3
  124. package/dist/templates/_executor/supervise.go +109 -0
  125. package/dist/templates/_executor/supervise_test.go +130 -0
  126. package/dist/templates/_executor/task_race_review_test.go +1 -1
  127. package/dist/templates/_executor/tasks.go +7 -8
  128. package/dist/templates/_executor/tasks_review_test.go +1 -1
  129. package/dist/templates/_executor/tasks_test.go +4 -4
  130. package/dist/templates/_executor/watch.go +8 -0
  131. package/dist/templates/_executor/watch_test.go +23 -2
  132. package/dist/templates/_executor/write_review_linux_test.go +4 -12
  133. package/dist/templates/_shared/AGENTS.md +129 -0
  134. package/dist/templates/binary/dsm-package.yaml +24 -0
  135. package/dist/templates/binary/i18n/messages/de.json +4 -0
  136. package/dist/templates/binary/i18n/messages/en.json +4 -0
  137. package/dist/templates/binary/i18n/messages/es.json +4 -0
  138. package/dist/templates/binary/i18n/messages/fr.json +4 -0
  139. package/dist/templates/binary/i18n/messages/it.json +4 -0
  140. package/dist/templates/binary/i18n/messages/ja.json +4 -0
  141. package/dist/templates/binary/i18n/messages/ko.json +4 -0
  142. package/dist/templates/binary/i18n/messages/zh-CN.json +4 -0
  143. package/dist/templates/binary/i18n/messages/zh-TW.json +4 -0
  144. package/dist/templates/binary/ui/app.js +19 -4
  145. package/dist/templates/native-authorization/AuthorizationGate.vue +5 -3
  146. package/dist/templates/native-authorization/i18n/de.json +1 -0
  147. package/dist/templates/native-authorization/i18n/en.json +1 -0
  148. package/dist/templates/native-authorization/i18n/es.json +2 -1
  149. package/dist/templates/native-authorization/i18n/fr.json +1 -0
  150. package/dist/templates/native-authorization/i18n/it.json +11 -10
  151. package/dist/templates/native-authorization/i18n/ja.json +1 -0
  152. package/dist/templates/native-authorization/i18n/ko.json +10 -9
  153. package/dist/templates/native-authorization/i18n/zh-CN.json +6 -5
  154. package/dist/templates/native-authorization/i18n/zh-TW.json +6 -5
  155. package/dist/templates/native-go/README.md +43 -10
  156. package/dist/templates/native-go/backend/cmd/app/main.go +27 -7
  157. package/dist/templates/native-go/backend/internal/api/entry_test.go +47 -0
  158. package/dist/templates/native-go/backend/internal/api/permissions_test.go +3 -3
  159. package/dist/templates/native-go/backend/internal/api/registry.go +11 -0
  160. package/dist/templates/native-go/backend/internal/api/sdk-permissions.json +14 -1
  161. package/dist/templates/native-go/backend/internal/api/server.go +18 -5
  162. package/dist/templates/native-go/backend/internal/app/delegate_config.go +57 -0
  163. package/dist/templates/native-go/backend/internal/app/delegate_config_test.go +28 -0
  164. package/dist/templates/native-go/backend/internal/app/portal.go +30 -0
  165. package/dist/templates/native-go/backend/internal/app/portal_test.go +55 -0
  166. package/dist/templates/native-go/backend/internal/app/routes.go +8 -2
  167. package/dist/templates/native-go/backend/internal/background/runner.go +1 -1
  168. package/dist/templates/native-go/backend/internal/background/store.go +16 -14
  169. package/dist/templates/native-go/backend/internal/dsm/admin.go +8 -2
  170. package/dist/templates/native-go/backend/internal/dsm/admin_linux.go +43 -13
  171. package/dist/templates/native-go/backend/internal/dsm/admin_linux_test.go +56 -0
  172. package/dist/templates/native-go/backend/internal/dsm/admin_other.go +4 -1
  173. package/dist/templates/native-go/backend/internal/dsm/apppriv.go +30 -0
  174. package/dist/templates/native-go/backend/internal/dsm/bridge_file.go +75 -0
  175. package/dist/templates/native-go/backend/internal/dsm/bridge_file_test.go +57 -0
  176. package/dist/templates/native-go/backend/internal/dsm/entry.go +177 -0
  177. package/dist/templates/native-go/backend/internal/dsm/entry_test.go +315 -0
  178. package/dist/templates/native-go/backend/internal/dsm/native/admin-armv7.elf +0 -0
  179. package/dist/templates/native-go/backend/internal/dsm/native/apppriv-aarch64.elf +0 -0
  180. package/dist/templates/native-go/backend/internal/dsm/native/apppriv-armv7.elf +0 -0
  181. package/dist/templates/native-go/backend/internal/dsm/native/apppriv-x86_64.elf +0 -0
  182. package/dist/templates/native-go/backend/internal/dsm/native/apppriv_check.c +33 -0
  183. package/dist/templates/native-go/backend/internal/dsm/native/build.sh +13 -4
  184. package/dist/templates/native-go/backend/internal/dsm/native/provenance.json +9 -3
  185. package/dist/templates/native-go/backend/internal/filestation/check_permission.go +71 -0
  186. package/dist/templates/native-go/backend/internal/filestation/check_permission_test.go +77 -0
  187. package/dist/templates/native-go/backend/internal/filestation/sdk_policy_test.go +39 -0
  188. package/dist/templates/native-go/backend/internal/filestation/service.go +1 -1
  189. package/dist/templates/native-go/backend/internal/portal/portal.go +138 -0
  190. package/dist/templates/native-go/backend/internal/portal/portal_test.go +89 -0
  191. package/dist/templates/native-go/dsm-package.yaml +20 -1
  192. package/dist/templates/native-go/i18n/glossary.json +2 -1
  193. package/dist/templates/native-go/i18n/messages/de.json +1 -0
  194. package/dist/templates/native-go/i18n/messages/en.json +1 -0
  195. package/dist/templates/native-go/i18n/messages/es.json +1 -0
  196. package/dist/templates/native-go/i18n/messages/fr.json +1 -0
  197. package/dist/templates/native-go/i18n/messages/it.json +1 -0
  198. package/dist/templates/native-go/i18n/messages/ja.json +1 -0
  199. package/dist/templates/native-go/i18n/messages/ko.json +1 -0
  200. package/dist/templates/native-go/i18n/messages/zh-CN.json +1 -0
  201. package/dist/templates/native-go/i18n/messages/zh-TW.json +1 -0
  202. package/dist/templates/native-go/ui/app.css +10 -0
  203. package/dist/templates/native-go/ui/app.js +11 -1
  204. package/dist/templates/native-go-delegate/DELEGATE.md +126 -5
  205. package/dist/templates/native-go-delegate/backend/cmd/background-worker/main.go +7 -0
  206. package/dist/templates/native-go-delegate/backend/internal/app/delegate.go +11 -1
  207. package/dist/templates/native-go-delegate/backend/internal/app/delegate_routes_test.go +14 -0
  208. package/dist/templates/native-go-delegate/backend/internal/background/delegated_moves.go +270 -0
  209. package/dist/templates/native-go-delegate/backend/internal/delegate/admission_recovery_test.go +410 -0
  210. package/dist/templates/native-go-delegate/backend/internal/delegate/cancel_contract_test.go +95 -0
  211. package/dist/templates/native-go-delegate/backend/internal/delegate/client.go +8 -0
  212. package/dist/templates/native-go-delegate/backend/internal/delegate/destination.go +110 -0
  213. package/dist/templates/native-go-delegate/backend/internal/delegate/destination_state.go +117 -0
  214. package/dist/templates/native-go-delegate/backend/internal/delegate/destination_state_test.go +60 -0
  215. package/dist/templates/native-go-delegate/backend/internal/delegate/destination_test.go +116 -0
  216. package/dist/templates/native-go-delegate/backend/internal/delegate/example.go +81 -0
  217. package/dist/templates/native-go-delegate/backend/internal/delegate/example_test.go +91 -0
  218. package/dist/templates/native-go-delegate/backend/internal/delegate/executor_contract_test.go +511 -0
  219. package/dist/templates/native-go-delegate/backend/internal/delegate/files.go +1 -1
  220. package/dist/templates/native-go-delegate/backend/internal/delegate/long_running_routes.go +92 -0
  221. package/dist/templates/native-go-delegate/backend/internal/delegate/long_running_routes_test.go +99 -0
  222. package/dist/templates/native-go-delegate/backend/internal/delegate/move.go +348 -0
  223. package/dist/templates/native-go-delegate/backend/internal/delegate/move_test.go +351 -0
  224. package/dist/templates/native-go-delegate/backend/internal/delegate/operations_list.go +65 -0
  225. package/dist/templates/native-go-delegate/backend/internal/delegate/operations_list_test.go +114 -0
  226. package/dist/templates/native-go-delegate/backend/internal/delegate/retry_test.go +1 -1
  227. package/dist/templates/native-go-delegate/backend/internal/delegate/service.go +58 -17
  228. package/dist/templates/native-go-delegate/backend/internal/delegate/staging.go +121 -0
  229. package/dist/templates/native-go-delegate/backend/internal/delegate/status_disabled_test.go +51 -0
  230. package/dist/templates/native-go-delegate/backend/internal/delegate/testdata/executor_contract.txt +112 -0
  231. package/dist/templates/native-go-delegate/backend/internal/delegate/transient_contract_test.go +137 -0
  232. package/dist/templates/native-go-delegate/backend/internal/filestation/files.go +1 -31
  233. package/dist/templates/native-go-delegate/frontend/src/CapabilityPanels.vue +30 -3
  234. package/dist/templates/native-go-delegate/frontend/src/delegate/BackgroundSavePanel.vue +113 -0
  235. package/dist/templates/native-go-delegate/frontend/src/delegate/copy.ts +5 -6
  236. package/dist/templates/native-go-delegate/frontend/test/background-save.test.ts +121 -0
  237. package/dist/templates/native-go-delegate/frontend/test/scope-settings.test.ts +49 -0
  238. package/dist/templates/native-go-delegate/test.sh +1 -0
  239. package/dist/templates/native-go-jobs/frontend/src/background/i18n/de.json +2 -2
  240. package/dist/templates/native-go-jobs/frontend/src/background/i18n/en.json +2 -2
  241. package/dist/templates/native-go-jobs/frontend/src/background/i18n/es.json +12 -12
  242. package/dist/templates/native-go-jobs/frontend/src/background/i18n/fr.json +4 -4
  243. package/dist/templates/native-go-jobs/frontend/src/background/i18n/it.json +17 -17
  244. package/dist/templates/native-go-jobs/frontend/src/background/i18n/ja.json +7 -7
  245. package/dist/templates/native-go-jobs/frontend/src/background/i18n/ko.json +15 -15
  246. package/dist/templates/native-go-jobs/frontend/src/background/i18n/zh-CN.json +3 -3
  247. package/dist/templates/native-go-jobs/frontend/src/background/i18n/zh-TW.json +2 -2
  248. package/dist/templates/native-go-jobs/frontend/test/background.test.ts +25 -28
  249. package/dist/templates/native-go-vue/README.md +4 -0
  250. package/dist/templates/native-go-vue/frontend/package-lock.json +4 -4
  251. package/dist/templates/native-go-vue/frontend/package.json +1 -1
  252. package/dist/templates/native-go-vue/frontend/src/App.vue +18 -13
  253. package/dist/templates/native-go-vue/frontend/src/context.ts +31 -0
  254. package/dist/templates/native-go-vue/frontend/src/delegate/ExecutorSettings.vue +52 -8
  255. package/dist/templates/native-go-vue/frontend/src/delegate/catalogs.ts +11 -0
  256. package/dist/templates/native-go-vue/frontend/src/delegate/copy.test.ts +12 -0
  257. package/dist/templates/native-go-vue/frontend/src/delegate/copy.ts +4 -4
  258. package/dist/templates/native-go-vue/frontend/src/delegate/executor-setup.ts +4 -2
  259. package/dist/templates/native-go-vue/frontend/src/delegate/facade.test.ts +100 -0
  260. package/dist/templates/native-go-vue/frontend/src/delegate/facade.ts +85 -0
  261. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/de.json +46 -0
  262. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/en.json +12 -2
  263. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/es.json +46 -0
  264. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/fr.json +46 -0
  265. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/it.json +46 -0
  266. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/ja.json +46 -0
  267. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/ko.json +46 -0
  268. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/de.json +42 -0
  269. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/en.json +42 -0
  270. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/es.json +42 -0
  271. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/fr.json +42 -0
  272. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/it.json +42 -0
  273. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/ja.json +42 -0
  274. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/ko.json +42 -0
  275. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/zh-CN.json +42 -0
  276. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/zh-TW.json +42 -0
  277. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/zh-CN.json +46 -0
  278. package/dist/templates/native-go-vue/frontend/src/delegate/i18n/zh-TW.json +15 -5
  279. package/dist/templates/native-go-vue/frontend/src/delegate/long-running.ts +57 -0
  280. package/dist/templates/native-go-vue/frontend/src/delegate/save-copy.test.ts +12 -0
  281. package/dist/templates/native-go-vue/frontend/src/delegate/save-copy.ts +24 -0
  282. package/dist/templates/native-go-vue/frontend/src/delegate/scoped-picker.test.ts +12 -0
  283. package/dist/templates/native-go-vue/frontend/src/delegate/scoped-picker.ts +21 -0
  284. package/dist/templates/native-go-vue/frontend/src/files/files.test.ts +7 -0
  285. package/dist/templates/native-go-vue/frontend/src/i18n/de.json +20 -0
  286. package/dist/templates/native-go-vue/frontend/src/i18n/en.json +20 -0
  287. package/dist/templates/native-go-vue/frontend/src/i18n/es.json +20 -0
  288. package/dist/templates/native-go-vue/frontend/src/i18n/fr.json +20 -0
  289. package/dist/templates/native-go-vue/frontend/src/i18n/it.json +20 -0
  290. package/dist/templates/native-go-vue/frontend/src/i18n/ja.json +20 -0
  291. package/dist/templates/native-go-vue/frontend/src/i18n/ko.json +20 -0
  292. package/dist/templates/native-go-vue/frontend/src/i18n/zh-CN.json +20 -0
  293. package/dist/templates/native-go-vue/frontend/src/i18n/zh-TW.json +20 -0
  294. package/dist/templates/native-go-vue/frontend/src/i18n.ts +13 -0
  295. package/dist/templates/native-go-vue/frontend/src/identity/LoginPage.vue +16 -14
  296. package/dist/templates/native-go-vue/frontend/src/identity/i18n/de.json +27 -0
  297. package/dist/templates/native-go-vue/frontend/src/identity/i18n/en.json +27 -0
  298. package/dist/templates/native-go-vue/frontend/src/identity/i18n/es.json +27 -0
  299. package/dist/templates/native-go-vue/frontend/src/identity/i18n/fr.json +27 -0
  300. package/dist/templates/native-go-vue/frontend/src/identity/i18n/it.json +27 -0
  301. package/dist/templates/native-go-vue/frontend/src/identity/i18n/ja.json +27 -0
  302. package/dist/templates/native-go-vue/frontend/src/identity/i18n/ko.json +27 -0
  303. package/dist/templates/native-go-vue/frontend/src/identity/i18n/zh-CN.json +27 -0
  304. package/dist/templates/native-go-vue/frontend/src/identity/i18n/zh-TW.json +27 -0
  305. package/dist/templates/native-go-vue/frontend/src/identity/i18n.ts +14 -0
  306. package/dist/templates/native-go-vue/frontend/src/identity/session.test.ts +4 -0
  307. package/dist/templates/native-go-vue/frontend/src/identity/session.ts +9 -8
  308. package/dist/templates/native-go-vue/frontend/src/nas/NasPicker.vue +31 -12
  309. package/dist/templates/native-go-vue/frontend/src/nas/destination.test.ts +48 -0
  310. package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/de.json +1 -1
  311. package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/en.json +1 -1
  312. package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/es.json +10 -10
  313. package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/fr.json +1 -1
  314. package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/it.json +12 -12
  315. package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/ja.json +15 -15
  316. package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/ko.json +12 -12
  317. package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/zh-CN.json +1 -1
  318. package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/zh-TW.json +1 -1
  319. package/dist/templates/native-go-vue/frontend/src/portal/PortalSettings.vue +39 -0
  320. package/dist/templates/native-go-vue/frontend/src/shell/i18n/fr.json +1 -1
  321. package/dist/templates/native-go-vue/frontend/src/shell/i18n/ja.json +1 -1
  322. package/dist/templates/native-go-vue/frontend/test/apps.test.ts +14 -0
  323. package/dist/templates/native-go-vue/frontend/test/portal-settings.test.ts +71 -0
  324. package/dist/templates/native-go-vue/frontend/test/shell-i18n.test.ts +50 -0
  325. package/package.json +5 -1
  326. package/schema/package-metadata.schema.json +101 -0
  327. package/schema/synology-app.schema.json +112 -0
  328. package/skills/SKILL.md +106 -4
  329. package/skills/reference/create.md +101 -2
  330. package/skills/reference/deploy.md +2 -2
  331. package/skills/reference/files.md +113 -2
  332. package/skills/reference/identity.md +70 -1
  333. package/skills/reference/portal.md +17 -0
  334. package/skills/reference/ui-vue.md +12 -0
  335. package/templates/_daemon/main_test.go +61 -8
  336. package/templates/_executor/README.md +127 -16
  337. package/templates/_executor/anchor.go +146 -0
  338. package/templates/_executor/anchor_test.go +126 -0
  339. package/templates/_executor/apppriv_review_test.go +1 -1
  340. package/templates/_executor/cancel_contract_test.go +236 -0
  341. package/templates/_executor/copy.go +64 -0
  342. package/templates/_executor/copy_test.go +88 -0
  343. package/templates/_executor/dsm.go +23 -10
  344. package/templates/_executor/dsm_test.go +95 -1
  345. package/templates/_executor/executor.go +260 -49
  346. package/templates/_executor/executor_test.go +36 -6
  347. package/templates/_executor/identity.go +27 -1
  348. package/templates/_executor/identity_kernel_linux_test.go +60 -0
  349. package/templates/_executor/identity_linux.go +82 -0
  350. package/templates/_executor/identity_security_test.go +43 -0
  351. package/templates/_executor/internal/lifecycle/lifecycle.go +5 -0
  352. package/templates/_executor/internal/lifecycle/lifecycle_test.go +61 -3
  353. package/templates/_executor/internal/taskscript/boot.sh +9 -9
  354. package/templates/_executor/internal/taskscript/cmd/main.go +2 -2
  355. package/templates/_executor/internal/taskscript/control.sh +15 -10
  356. package/templates/_executor/internal/taskscript/tasks.go +5 -3
  357. package/templates/_executor/lifecycle_test.go +11 -0
  358. package/templates/_executor/link_linux.go +28 -0
  359. package/templates/_executor/long_running_test.go +530 -0
  360. package/templates/_executor/main.go +72 -20
  361. package/templates/_executor/move_linux.go +490 -0
  362. package/templates/_executor/move_linux_test.go +460 -0
  363. package/templates/_executor/move_validation.go +46 -0
  364. package/templates/_executor/move_validation_test.go +187 -0
  365. package/templates/_executor/operations.go +926 -0
  366. package/templates/_executor/platform_linux.go +24 -173
  367. package/templates/_executor/platform_linux_test.go +9 -65
  368. package/templates/_executor/platform_other.go +30 -4
  369. package/templates/_executor/process.go +3 -0
  370. package/templates/_executor/records.go +242 -0
  371. package/templates/_executor/scope_cancel_contract_test.go +91 -0
  372. package/templates/_executor/scope_client.go +37 -0
  373. package/templates/_executor/scope_contract.go +12 -0
  374. package/templates/_executor/selected_scope.go +146 -0
  375. package/templates/_executor/selected_scope_test.go +186 -0
  376. package/templates/_executor/status_disabled_test.go +33 -0
  377. package/templates/_executor/store.go +4 -3
  378. package/templates/_executor/supervise.go +109 -0
  379. package/templates/_executor/supervise_test.go +130 -0
  380. package/templates/_executor/task_race_review_test.go +1 -1
  381. package/templates/_executor/tasks.go +7 -8
  382. package/templates/_executor/tasks_review_test.go +1 -1
  383. package/templates/_executor/tasks_test.go +4 -4
  384. package/templates/_executor/watch.go +8 -0
  385. package/templates/_executor/watch_test.go +23 -2
  386. package/templates/_executor/write_review_linux_test.go +4 -12
  387. package/templates/_shared/AGENTS.md +129 -0
  388. package/templates/binary/dsm-package.yaml +24 -0
  389. package/templates/binary/i18n/messages/de.json +4 -0
  390. package/templates/binary/i18n/messages/en.json +4 -0
  391. package/templates/binary/i18n/messages/es.json +4 -0
  392. package/templates/binary/i18n/messages/fr.json +4 -0
  393. package/templates/binary/i18n/messages/it.json +4 -0
  394. package/templates/binary/i18n/messages/ja.json +4 -0
  395. package/templates/binary/i18n/messages/ko.json +4 -0
  396. package/templates/binary/i18n/messages/zh-CN.json +4 -0
  397. package/templates/binary/i18n/messages/zh-TW.json +4 -0
  398. package/templates/binary/ui/app.js +19 -4
  399. package/templates/native-authorization/AuthorizationGate.vue +5 -3
  400. package/templates/native-authorization/i18n/de.json +1 -0
  401. package/templates/native-authorization/i18n/en.json +1 -0
  402. package/templates/native-authorization/i18n/es.json +2 -1
  403. package/templates/native-authorization/i18n/fr.json +1 -0
  404. package/templates/native-authorization/i18n/it.json +11 -10
  405. package/templates/native-authorization/i18n/ja.json +1 -0
  406. package/templates/native-authorization/i18n/ko.json +10 -9
  407. package/templates/native-authorization/i18n/zh-CN.json +6 -5
  408. package/templates/native-authorization/i18n/zh-TW.json +6 -5
  409. package/templates/native-go/README.md +43 -10
  410. package/templates/native-go/backend/cmd/app/main.go +27 -7
  411. package/templates/native-go/backend/internal/api/entry_test.go +47 -0
  412. package/templates/native-go/backend/internal/api/permissions_test.go +3 -3
  413. package/templates/native-go/backend/internal/api/registry.go +11 -0
  414. package/templates/native-go/backend/internal/api/sdk-permissions.json +14 -1
  415. package/templates/native-go/backend/internal/api/server.go +18 -5
  416. package/templates/native-go/backend/internal/app/delegate_config.go +57 -0
  417. package/templates/native-go/backend/internal/app/delegate_config_test.go +28 -0
  418. package/templates/native-go/backend/internal/app/portal.go +30 -0
  419. package/templates/native-go/backend/internal/app/portal_test.go +55 -0
  420. package/templates/native-go/backend/internal/app/routes.go +8 -2
  421. package/templates/native-go/backend/internal/background/runner.go +1 -1
  422. package/templates/native-go/backend/internal/background/store.go +16 -14
  423. package/templates/native-go/backend/internal/dsm/admin.go +8 -2
  424. package/templates/native-go/backend/internal/dsm/admin_linux.go +43 -13
  425. package/templates/native-go/backend/internal/dsm/admin_linux_test.go +56 -0
  426. package/templates/native-go/backend/internal/dsm/admin_other.go +4 -1
  427. package/templates/native-go/backend/internal/dsm/apppriv.go +30 -0
  428. package/templates/native-go/backend/internal/dsm/bridge_file.go +75 -0
  429. package/templates/native-go/backend/internal/dsm/bridge_file_test.go +57 -0
  430. package/templates/native-go/backend/internal/dsm/entry.go +177 -0
  431. package/templates/native-go/backend/internal/dsm/entry_test.go +315 -0
  432. package/templates/native-go/backend/internal/dsm/native/admin-armv7.elf +0 -0
  433. package/templates/native-go/backend/internal/dsm/native/apppriv-aarch64.elf +0 -0
  434. package/templates/native-go/backend/internal/dsm/native/apppriv-armv7.elf +0 -0
  435. package/templates/native-go/backend/internal/dsm/native/apppriv-x86_64.elf +0 -0
  436. package/templates/native-go/backend/internal/dsm/native/apppriv_check.c +33 -0
  437. package/templates/native-go/backend/internal/dsm/native/build.sh +13 -4
  438. package/templates/native-go/backend/internal/dsm/native/provenance.json +9 -3
  439. package/templates/native-go/backend/internal/filestation/check_permission.go +71 -0
  440. package/templates/native-go/backend/internal/filestation/check_permission_test.go +77 -0
  441. package/templates/native-go/backend/internal/filestation/sdk_policy_test.go +39 -0
  442. package/templates/native-go/backend/internal/filestation/service.go +1 -1
  443. package/templates/native-go/backend/internal/portal/portal.go +138 -0
  444. package/templates/native-go/backend/internal/portal/portal_test.go +89 -0
  445. package/templates/native-go/dsm-package.yaml +20 -1
  446. package/templates/native-go/i18n/glossary.json +2 -1
  447. package/templates/native-go/i18n/messages/de.json +1 -0
  448. package/templates/native-go/i18n/messages/en.json +1 -0
  449. package/templates/native-go/i18n/messages/es.json +1 -0
  450. package/templates/native-go/i18n/messages/fr.json +1 -0
  451. package/templates/native-go/i18n/messages/it.json +1 -0
  452. package/templates/native-go/i18n/messages/ja.json +1 -0
  453. package/templates/native-go/i18n/messages/ko.json +1 -0
  454. package/templates/native-go/i18n/messages/zh-CN.json +1 -0
  455. package/templates/native-go/i18n/messages/zh-TW.json +1 -0
  456. package/templates/native-go/ui/app.css +10 -0
  457. package/templates/native-go/ui/app.js +11 -1
  458. package/templates/native-go-delegate/DELEGATE.md +126 -5
  459. package/templates/native-go-delegate/backend/cmd/background-worker/main.go +7 -0
  460. package/templates/native-go-delegate/backend/internal/app/delegate.go +11 -1
  461. package/templates/native-go-delegate/backend/internal/app/delegate_routes_test.go +14 -0
  462. package/templates/native-go-delegate/backend/internal/background/delegated_moves.go +270 -0
  463. package/templates/native-go-delegate/backend/internal/delegate/admission_recovery_test.go +410 -0
  464. package/templates/native-go-delegate/backend/internal/delegate/cancel_contract_test.go +95 -0
  465. package/templates/native-go-delegate/backend/internal/delegate/client.go +8 -0
  466. package/templates/native-go-delegate/backend/internal/delegate/destination.go +110 -0
  467. package/templates/native-go-delegate/backend/internal/delegate/destination_state.go +117 -0
  468. package/templates/native-go-delegate/backend/internal/delegate/destination_state_test.go +60 -0
  469. package/templates/native-go-delegate/backend/internal/delegate/destination_test.go +116 -0
  470. package/templates/native-go-delegate/backend/internal/delegate/example.go +81 -0
  471. package/templates/native-go-delegate/backend/internal/delegate/example_test.go +91 -0
  472. package/templates/native-go-delegate/backend/internal/delegate/executor_contract_test.go +511 -0
  473. package/templates/native-go-delegate/backend/internal/delegate/files.go +1 -1
  474. package/templates/native-go-delegate/backend/internal/delegate/long_running_routes.go +92 -0
  475. package/templates/native-go-delegate/backend/internal/delegate/long_running_routes_test.go +99 -0
  476. package/templates/native-go-delegate/backend/internal/delegate/move.go +348 -0
  477. package/templates/native-go-delegate/backend/internal/delegate/move_test.go +351 -0
  478. package/templates/native-go-delegate/backend/internal/delegate/operations_list.go +65 -0
  479. package/templates/native-go-delegate/backend/internal/delegate/operations_list_test.go +114 -0
  480. package/templates/native-go-delegate/backend/internal/delegate/retry_test.go +1 -1
  481. package/templates/native-go-delegate/backend/internal/delegate/service.go +58 -17
  482. package/templates/native-go-delegate/backend/internal/delegate/staging.go +121 -0
  483. package/templates/native-go-delegate/backend/internal/delegate/status_disabled_test.go +51 -0
  484. package/templates/native-go-delegate/backend/internal/delegate/testdata/executor_contract.txt +112 -0
  485. package/templates/native-go-delegate/backend/internal/delegate/transient_contract_test.go +137 -0
  486. package/templates/native-go-delegate/backend/internal/filestation/files.go +1 -31
  487. package/templates/native-go-delegate/frontend/src/CapabilityPanels.vue +30 -3
  488. package/templates/native-go-delegate/frontend/src/delegate/BackgroundSavePanel.vue +113 -0
  489. package/templates/native-go-delegate/frontend/src/delegate/copy.ts +5 -6
  490. package/templates/native-go-delegate/frontend/test/background-save.test.ts +121 -0
  491. package/templates/native-go-delegate/frontend/test/scope-settings.test.ts +49 -0
  492. package/templates/native-go-delegate/test.sh +1 -0
  493. package/templates/native-go-jobs/frontend/src/background/i18n/de.json +2 -2
  494. package/templates/native-go-jobs/frontend/src/background/i18n/en.json +2 -2
  495. package/templates/native-go-jobs/frontend/src/background/i18n/es.json +12 -12
  496. package/templates/native-go-jobs/frontend/src/background/i18n/fr.json +4 -4
  497. package/templates/native-go-jobs/frontend/src/background/i18n/it.json +17 -17
  498. package/templates/native-go-jobs/frontend/src/background/i18n/ja.json +7 -7
  499. package/templates/native-go-jobs/frontend/src/background/i18n/ko.json +15 -15
  500. package/templates/native-go-jobs/frontend/src/background/i18n/zh-CN.json +3 -3
  501. package/templates/native-go-jobs/frontend/src/background/i18n/zh-TW.json +2 -2
  502. package/templates/native-go-jobs/frontend/test/background.test.ts +25 -28
  503. package/templates/native-go-vue/README.md +4 -0
  504. package/templates/native-go-vue/frontend/package-lock.json +4 -4
  505. package/templates/native-go-vue/frontend/package.json +1 -1
  506. package/templates/native-go-vue/frontend/src/App.vue +18 -13
  507. package/templates/native-go-vue/frontend/src/context.ts +31 -0
  508. package/templates/native-go-vue/frontend/src/delegate/ExecutorSettings.vue +52 -8
  509. package/templates/native-go-vue/frontend/src/delegate/catalogs.ts +11 -0
  510. package/templates/native-go-vue/frontend/src/delegate/copy.test.ts +12 -0
  511. package/templates/native-go-vue/frontend/src/delegate/copy.ts +4 -4
  512. package/templates/native-go-vue/frontend/src/delegate/executor-setup.ts +4 -2
  513. package/templates/native-go-vue/frontend/src/delegate/facade.test.ts +100 -0
  514. package/templates/native-go-vue/frontend/src/delegate/facade.ts +85 -0
  515. package/templates/native-go-vue/frontend/src/delegate/i18n/de.json +46 -0
  516. package/templates/native-go-vue/frontend/src/delegate/i18n/en.json +12 -2
  517. package/templates/native-go-vue/frontend/src/delegate/i18n/es.json +46 -0
  518. package/templates/native-go-vue/frontend/src/delegate/i18n/fr.json +46 -0
  519. package/templates/native-go-vue/frontend/src/delegate/i18n/it.json +46 -0
  520. package/templates/native-go-vue/frontend/src/delegate/i18n/ja.json +46 -0
  521. package/templates/native-go-vue/frontend/src/delegate/i18n/ko.json +46 -0
  522. package/templates/native-go-vue/frontend/src/delegate/i18n/save/de.json +42 -0
  523. package/templates/native-go-vue/frontend/src/delegate/i18n/save/en.json +42 -0
  524. package/templates/native-go-vue/frontend/src/delegate/i18n/save/es.json +42 -0
  525. package/templates/native-go-vue/frontend/src/delegate/i18n/save/fr.json +42 -0
  526. package/templates/native-go-vue/frontend/src/delegate/i18n/save/it.json +42 -0
  527. package/templates/native-go-vue/frontend/src/delegate/i18n/save/ja.json +42 -0
  528. package/templates/native-go-vue/frontend/src/delegate/i18n/save/ko.json +42 -0
  529. package/templates/native-go-vue/frontend/src/delegate/i18n/save/zh-CN.json +42 -0
  530. package/templates/native-go-vue/frontend/src/delegate/i18n/save/zh-TW.json +42 -0
  531. package/templates/native-go-vue/frontend/src/delegate/i18n/zh-CN.json +46 -0
  532. package/templates/native-go-vue/frontend/src/delegate/i18n/zh-TW.json +15 -5
  533. package/templates/native-go-vue/frontend/src/delegate/long-running.ts +57 -0
  534. package/templates/native-go-vue/frontend/src/delegate/save-copy.test.ts +12 -0
  535. package/templates/native-go-vue/frontend/src/delegate/save-copy.ts +24 -0
  536. package/templates/native-go-vue/frontend/src/delegate/scoped-picker.test.ts +12 -0
  537. package/templates/native-go-vue/frontend/src/delegate/scoped-picker.ts +21 -0
  538. package/templates/native-go-vue/frontend/src/files/files.test.ts +7 -0
  539. package/templates/native-go-vue/frontend/src/i18n/de.json +20 -0
  540. package/templates/native-go-vue/frontend/src/i18n/en.json +20 -0
  541. package/templates/native-go-vue/frontend/src/i18n/es.json +20 -0
  542. package/templates/native-go-vue/frontend/src/i18n/fr.json +20 -0
  543. package/templates/native-go-vue/frontend/src/i18n/it.json +20 -0
  544. package/templates/native-go-vue/frontend/src/i18n/ja.json +20 -0
  545. package/templates/native-go-vue/frontend/src/i18n/ko.json +20 -0
  546. package/templates/native-go-vue/frontend/src/i18n/zh-CN.json +20 -0
  547. package/templates/native-go-vue/frontend/src/i18n/zh-TW.json +20 -0
  548. package/templates/native-go-vue/frontend/src/i18n.ts +13 -0
  549. package/templates/native-go-vue/frontend/src/identity/LoginPage.vue +16 -14
  550. package/templates/native-go-vue/frontend/src/identity/i18n/de.json +27 -0
  551. package/templates/native-go-vue/frontend/src/identity/i18n/en.json +27 -0
  552. package/templates/native-go-vue/frontend/src/identity/i18n/es.json +27 -0
  553. package/templates/native-go-vue/frontend/src/identity/i18n/fr.json +27 -0
  554. package/templates/native-go-vue/frontend/src/identity/i18n/it.json +27 -0
  555. package/templates/native-go-vue/frontend/src/identity/i18n/ja.json +27 -0
  556. package/templates/native-go-vue/frontend/src/identity/i18n/ko.json +27 -0
  557. package/templates/native-go-vue/frontend/src/identity/i18n/zh-CN.json +27 -0
  558. package/templates/native-go-vue/frontend/src/identity/i18n/zh-TW.json +27 -0
  559. package/templates/native-go-vue/frontend/src/identity/i18n.ts +14 -0
  560. package/templates/native-go-vue/frontend/src/identity/session.test.ts +4 -0
  561. package/templates/native-go-vue/frontend/src/identity/session.ts +9 -8
  562. package/templates/native-go-vue/frontend/src/nas/NasPicker.vue +31 -12
  563. package/templates/native-go-vue/frontend/src/nas/destination.test.ts +48 -0
  564. package/templates/native-go-vue/frontend/src/nas/i18n/files/de.json +1 -1
  565. package/templates/native-go-vue/frontend/src/nas/i18n/files/en.json +1 -1
  566. package/templates/native-go-vue/frontend/src/nas/i18n/files/es.json +10 -10
  567. package/templates/native-go-vue/frontend/src/nas/i18n/files/fr.json +1 -1
  568. package/templates/native-go-vue/frontend/src/nas/i18n/files/it.json +12 -12
  569. package/templates/native-go-vue/frontend/src/nas/i18n/files/ja.json +15 -15
  570. package/templates/native-go-vue/frontend/src/nas/i18n/files/ko.json +12 -12
  571. package/templates/native-go-vue/frontend/src/nas/i18n/files/zh-CN.json +1 -1
  572. package/templates/native-go-vue/frontend/src/nas/i18n/files/zh-TW.json +1 -1
  573. package/templates/native-go-vue/frontend/src/portal/PortalSettings.vue +39 -0
  574. package/templates/native-go-vue/frontend/src/shell/i18n/fr.json +1 -1
  575. package/templates/native-go-vue/frontend/src/shell/i18n/ja.json +1 -1
  576. package/templates/native-go-vue/frontend/test/apps.test.ts +14 -0
  577. package/templates/native-go-vue/frontend/test/portal-settings.test.ts +71 -0
  578. package/templates/native-go-vue/frontend/test/shell-i18n.test.ts +50 -0
@@ -0,0 +1,27 @@
1
+ {
2
+ "title": "Accedi con l’account Synology",
3
+ "intro": "Usare l’account di questo NAS per accedere all’app.",
4
+ "httpsTitle": "HTTPS obbligatorio",
5
+ "failedTitle": "Accesso non riuscito",
6
+ "account": "Account",
7
+ "password": "Password",
8
+ "otpPrompt": "Inserire il codice di verifica dell’app di autenticazione.",
9
+ "otp": "Codice di verifica",
10
+ "signingIn": "Accesso in corso…",
11
+ "verify": "Verifica e accedi",
12
+ "signIn": "Accedi",
13
+ "otherAccount": "Usa un altro account",
14
+ "continueDSM": "Continua con DSM",
15
+ "errors": {
16
+ "rate_limited": "Troppi tentativi di accesso. Attendere un minuto e riprovare.",
17
+ "https_required": "Aprire questa app tramite HTTPS per accedere.",
18
+ "auth_unavailable": "L’accesso a DSM non è disponibile. Riprovare.",
19
+ "session_required": "Accedere a DSM in questo browser, quindi riprovare.",
20
+ "failed": "Impossibile completare l’accesso. Controllare le credenziali o contattare l’amministratore."
21
+ },
22
+ "notices": {
23
+ "expired": "La sessione è scaduta. Accedere di nuovo.",
24
+ "revalidate": "Accedere a DSM in questo browser, quindi scegliere «Continua con DSM».",
25
+ "unavailable": "L’accesso non è disponibile. Aggiornare e riprovare."
26
+ }
27
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "title": "Synology アカウントでサインイン",
3
+ "intro": "この NAS のアカウントを使ってアプリにサインインします。",
4
+ "httpsTitle": "HTTPS が必要です",
5
+ "failedTitle": "サインインに失敗しました",
6
+ "account": "アカウント",
7
+ "password": "パスワード",
8
+ "otpPrompt": "認証アプリに表示された確認コードを入力してください。",
9
+ "otp": "確認コード",
10
+ "signingIn": "サインインしています…",
11
+ "verify": "確認してサインイン",
12
+ "signIn": "サインイン",
13
+ "otherAccount": "別のアカウントを使用",
14
+ "continueDSM": "DSM で続行",
15
+ "errors": {
16
+ "rate_limited": "サインインの試行回数が多すぎます。1 分待ってからもう一度お試しください。",
17
+ "https_required": "サインインするには HTTPS でこのアプリを開いてください。",
18
+ "auth_unavailable": "DSM サインインを利用できません。もう一度お試しください。",
19
+ "session_required": "このブラウザーで DSM にサインインしてから、もう一度お試しください。",
20
+ "failed": "サインインを完了できませんでした。アカウントとパスワードを確認するか、管理者に連絡してください。"
21
+ },
22
+ "notices": {
23
+ "expired": "セッションの有効期限が切れました。もう一度サインインしてください。",
24
+ "revalidate": "このブラウザーで DSM にサインインしてから、「DSM で続行」を選択してください。",
25
+ "unavailable": "サインインを利用できません。最新の情報に更新してから、もう一度お試しください。"
26
+ }
27
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "title": "Synology 계정으로 로그인",
3
+ "intro": "이 NAS의 계정을 사용하여 앱에 로그인합니다.",
4
+ "httpsTitle": "HTTPS 필요",
5
+ "failedTitle": "로그인 실패",
6
+ "account": "계정",
7
+ "password": "암호",
8
+ "otpPrompt": "인증 앱에 표시된 인증 코드를 입력하십시오.",
9
+ "otp": "인증 코드",
10
+ "signingIn": "로그인 중…",
11
+ "verify": "인증 후 로그인",
12
+ "signIn": "로그인",
13
+ "otherAccount": "다른 계정 사용",
14
+ "continueDSM": "DSM으로 계속",
15
+ "errors": {
16
+ "rate_limited": "로그인 시도 횟수가 너무 많습니다. 1분 후 다시 시도하십시오.",
17
+ "https_required": "로그인하려면 HTTPS로 이 앱을 여십시오.",
18
+ "auth_unavailable": "DSM 로그인을 사용할 수 없습니다. 다시 시도하십시오.",
19
+ "session_required": "이 브라우저에서 DSM에 로그인한 후 다시 시도하십시오.",
20
+ "failed": "로그인을 완료할 수 없습니다. 계정과 암호를 확인하거나 관리자에게 문의하십시오."
21
+ },
22
+ "notices": {
23
+ "expired": "세션이 만료되었습니다. 다시 로그인하십시오.",
24
+ "revalidate": "이 브라우저에서 DSM에 로그인한 후 ‘DSM으로 계속’을 선택하십시오.",
25
+ "unavailable": "로그인을 사용할 수 없습니다. 새로 고친 후 다시 시도하십시오."
26
+ }
27
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "title": "使用 Synology 帐户登录",
3
+ "intro": "使用这台 NAS 上的帐户登录此 App。",
4
+ "httpsTitle": "需要 HTTPS",
5
+ "failedTitle": "登录失败",
6
+ "account": "帐户",
7
+ "password": "密码",
8
+ "otpPrompt": "请输入身份验证器 App 中的验证码。",
9
+ "otp": "验证码",
10
+ "signingIn": "正在登录…",
11
+ "verify": "验证并登录",
12
+ "signIn": "登录",
13
+ "otherAccount": "使用其他帐户",
14
+ "continueDSM": "通过 DSM 继续",
15
+ "errors": {
16
+ "rate_limited": "登录尝试次数过多,请等待一分钟后重试。",
17
+ "https_required": "请使用 HTTPS 打开此 App 以登录。",
18
+ "auth_unavailable": "DSM 登录暂时不可用,请重试。",
19
+ "session_required": "请先在此浏览器中登录 DSM,然后重试。",
20
+ "failed": "无法完成登录。请检查帐户和密码,或联系管理员。"
21
+ },
22
+ "notices": {
23
+ "expired": "登录已过期,请重新登录。",
24
+ "revalidate": "请先在此浏览器中登录 DSM,然后选择“通过 DSM 继续”。",
25
+ "unavailable": "登录暂时不可用,请刷新后重试。"
26
+ }
27
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "title": "使用 Synology 帳號登入",
3
+ "intro": "使用這台 NAS 上的帳號登入此 App。",
4
+ "httpsTitle": "需要 HTTPS",
5
+ "failedTitle": "登入失敗",
6
+ "account": "帳號",
7
+ "password": "密碼",
8
+ "otpPrompt": "請輸入驗證器 App 中的驗證碼。",
9
+ "otp": "驗證碼",
10
+ "signingIn": "正在登入…",
11
+ "verify": "驗證並登入",
12
+ "signIn": "登入",
13
+ "otherAccount": "使用其他帳號",
14
+ "continueDSM": "以 DSM 繼續",
15
+ "errors": {
16
+ "rate_limited": "登入嘗試次數過多,請等候一分鐘再試。",
17
+ "https_required": "請使用 HTTPS 開啟此 App 以登入。",
18
+ "auth_unavailable": "DSM 登入目前無法使用,請再試一次。",
19
+ "session_required": "請先在此瀏覽器登入 DSM,然後再試一次。",
20
+ "failed": "無法完成登入。請檢查帳號與密碼,或聯絡管理員。"
21
+ },
22
+ "notices": {
23
+ "expired": "登入已逾時,請重新登入。",
24
+ "revalidate": "請先在此瀏覽器登入 DSM,然後選擇「以 DSM 繼續」。",
25
+ "unavailable": "登入目前無法使用,請重新整理後再試。"
26
+ }
27
+ }
@@ -0,0 +1,14 @@
1
+ import en from './i18n/en.json'
2
+ import zhTW from './i18n/zh-TW.json'
3
+ import zhCN from './i18n/zh-CN.json'
4
+ import ja from './i18n/ja.json'
5
+ import ko from './i18n/ko.json'
6
+ import de from './i18n/de.json'
7
+ import fr from './i18n/fr.json'
8
+ import es from './i18n/es.json'
9
+ import it from './i18n/it.json'
10
+ import {uiLocale} from '../nas/locale'
11
+ export type IdentityCopy=typeof en
12
+ export type IdentityNotice=''|keyof IdentityCopy['notices']
13
+ export const identityCatalogs:Record<string,IdentityCopy>={en,'zh-TW':zhTW,'zh-CN':zhCN,ja,ko,de,fr,es,it}
14
+ export function identityCopy(locale:string):IdentityCopy{return identityCatalogs[uiLocale(locale)]!}
@@ -8,6 +8,10 @@ test('discovers disabled identity without changing existing transport',async()=>
8
8
  const call=vi.fn().mockRejectedValue({code:'unknown_method'})
9
9
  const session=createSession(context(call));await session.start();expect(session.enabled.value).toBe(false);expect(session.ready.value).toBe(true);session.dispose()
10
10
  })
11
+ test('an Application Privileges refusal keeps the DSM shell instead of offering sign-in',async()=>{
12
+ const call=vi.fn().mockRejectedValue({code:'app_privilege_denied'})
13
+ const session=createSession(context(call));await session.start();expect(session.enabled.value).toBe(false);expect(session.notice.value).toBe('');session.dispose()
14
+ })
11
15
  test('bootstraps, expires and returns to login after a business rejection',async()=>{
12
16
  vi.useFakeTimers();const expiresAt=new Date(Date.now()+60000).toISOString()
13
17
  const call=vi.fn().mockResolvedValueOnce({enabled:true}).mockResolvedValueOnce({user:'alice',uid:'1205',expiresAt})
@@ -1,28 +1,29 @@
1
1
  import {ref} from 'vue'
2
2
  import type {Context} from '../context'
3
+ import type {IdentityNotice} from './i18n'
3
4
 
4
5
  export interface SessionSubject {user: string; uid: string; expiresAt: string}
5
6
  export function createSession(ctx: Context) {
6
7
  const enabled = ref(false)
7
8
  const ready = ref(false)
8
9
  const subject = ref<SessionSubject>()
9
- const notice = ref('')
10
+ const notice = ref<IdentityNotice>('')
10
11
  let disposed = false
11
12
  let revision = 0
12
13
  let expiry: ReturnType<typeof setTimeout> | undefined
13
14
  let poll: ReturnType<typeof setTimeout> | undefined
14
15
  function cancelTimers() {clearTimeout(expiry); clearTimeout(poll)}
15
- function clear(message = '') {revision++; cancelTimers(); subject.value = undefined; notice.value = message}
16
+ function clear(message: IdentityNotice = '') {revision++; cancelTimers(); subject.value = undefined; notice.value = message}
16
17
  function accept(value: SessionSubject) {
17
18
  if (disposed) return
18
19
  const remaining = Date.parse(value.expiresAt) - Date.now()
19
- if (!Number.isFinite(remaining) || remaining <= 0) {clear('Your session expired. Sign in again.'); return}
20
+ if (!Number.isFinite(remaining) || remaining <= 0) {clear('expired'); return}
20
21
  cancelTimers(); subject.value = value; notice.value = ''
21
- expiry = setTimeout(() => clear('Your session expired. Sign in again.'), remaining)
22
+ expiry = setTimeout(() => clear('expired'), remaining)
22
23
  const current = revision
23
24
  poll = setTimeout(async () => {
24
25
  try {const next = await ctx.call<SessionSubject>('identity.session'); if (!disposed && revision === current) accept(next)}
25
- catch {if (!disposed && revision === current) clear('Your session expired. Sign in again.')}
26
+ catch {if (!disposed && revision === current) clear('expired')}
26
27
  }, Math.min(60000, remaining))
27
28
  }
28
29
  async function start() {
@@ -37,8 +38,8 @@ export function createSession(ctx: Context) {
37
38
  } catch (e) {
38
39
  // Existing templates have no identity transport and retain their DSM shell.
39
40
  const code = (e as {code?: string})?.code
40
- enabled.value = !['unknown_method', 'admin_required', 'session_required'].includes(code || '')
41
- if (enabled.value) notice.value = 'Sign-in is unavailable. Refresh to try again.'
41
+ enabled.value = !['unknown_method', 'admin_required', 'app_privilege_denied', 'session_required'].includes(code || '')
42
+ if (enabled.value) notice.value = 'unavailable'
42
43
  } finally {if (!disposed) ready.value = true}
43
44
  }
44
45
  async function call<T = unknown>(method: string, params?: Record<string, unknown>): Promise<T> {
@@ -51,7 +52,7 @@ export function createSession(ctx: Context) {
51
52
  catch (e) {
52
53
  const code = (e as {code?: string})?.code
53
54
  if (!disposed && current === revision && enabled.value && ['session_required', 'session_revalidation_required'].includes(code || '')) {
54
- clear(code === 'session_revalidation_required' ? 'Sign in to DSM in this browser, then choose Continue with DSM.' : 'Your session expired. Sign in again.')
55
+ clear(code === 'session_revalidation_required' ? 'revalidate' : 'expired')
55
56
  }
56
57
  throw e
57
58
  }
@@ -1,23 +1,42 @@
1
1
  <script setup lang="ts">
2
- import {computed,ref,watch} from 'vue'
3
- import {Button,Dialog} from '@synopackageland/ui'
2
+ import {computed,onBeforeUnmount,ref,watch} from 'vue'
3
+ import {Button,Callout,Dialog} from '@synopackageland/ui'
4
4
  import FileBrowser from '../files/FileBrowser.vue'
5
5
  import type {NasProvider} from './contract'
6
6
  import {nasCopy} from './locale'
7
- const props=defineProps<{open:boolean;locale:string;provider:NasProvider;mode:'folder'|'file';title?:string;description?:string}>()
8
- const emit=defineEmits<{'update:open':[value:boolean];selected:[path:string]}>()
9
- const selected=ref<string>(),copy=computed(()=>nasCopy(props.locale))
10
- watch(()=>props.open,()=>{selected.value=undefined})
11
- function close(){selected.value=undefined;emit('update:open',false)}
12
- function confirm(){if(selected.value){emit('selected',selected.value);close()}}
7
+ import type {DestinationGrant,DestinationSelection} from '../delegate/long-running'
8
+ import {saveCopy,saveError} from '../delegate/save-copy'
9
+ const props=defineProps<{open:boolean;locale:string;provider:NasProvider;mode:'folder'|'file';title?:string;description?:string;destination?:DestinationSelection}>()
10
+ const emit=defineEmits<{'update:open':[value:boolean];selected:[path:string];authorized:[grant:DestinationGrant]}>()
11
+ const selected=ref<string>(),copy=computed(()=>nasCopy(props.locale)),save=computed(()=>saveCopy(props.locale)),busy=ref(false),error=ref<unknown>()
12
+ let generation=0,disposed=false
13
+ watch(()=>props.open,()=>{generation++;selected.value=undefined;error.value=undefined})
14
+ onBeforeUnmount(()=>{disposed=true;generation++})
15
+ function close(){if(busy.value)return;selected.value=undefined;emit('update:open',false)}
16
+ async function confirm(){
17
+ const path=selected.value,destination=props.destination,version=generation
18
+ if(!path||busy.value||!props.open||disposed||(destination&&props.mode!=='folder'))return
19
+ if(!destination){emit('selected',path);close();return}
20
+ busy.value=true;error.value=undefined
21
+ try{
22
+ const grant=await destination.selectDestination({key:destination.key,path})
23
+ if(disposed||version!==generation)return
24
+ if(!grant||typeof grant.id!=='string'||!grant.id||typeof grant.username!=='string'||!grant.username||grant.path!==path||grant.key!==destination.key||grant.lifetime!=='until-revoked')throw {code:'commit-uncertain'}
25
+ emit('authorized',grant);busy.value=false;close()
26
+ }catch(e){if(!disposed&&version===generation)error.value=e}
27
+ finally{if(!disposed)busy.value=false}
28
+ }
13
29
  </script>
14
30
  <template>
15
- <Dialog :open="open" :title="title??(mode==='folder'?copy.choose:copy.chooseFile)" :close-label="copy.close" width="800px" @update:open="value=>{if(!value)close()}">
16
- <p v-if="description">{{ description }}</p>
17
- <div class="nas-picker-content"><FileBrowser v-if="open" :provider="provider" :locale="locale" :mode="mode" @selected="selected=$event" /></div>
18
- <template #footer><Button variant="secondary" @click="close">{{ copy.cancel }}</Button><Button variant="primary" :disabled="!selected" @click="confirm">{{ copy.confirm }}</Button></template>
31
+ <Dialog :open="open" :title="title??(mode==='folder'?copy.choose:copy.chooseFile)" :description="description??copy.ownPermissions" :close-label="copy.close" :show-close="!busy" width="800px" @escape-key-down="event=>{if(busy)event.preventDefault()}" @interact-outside="event=>{if(busy)event.preventDefault()}" @update:open="value=>{if(!value)close()}">
32
+ <p v-if="destination" class="save-consent">{{ save.selection }}</p>
33
+ <Callout v-if="error" tone="danger" role="alert" class="save-message">{{ saveError(error,save) }}</Callout>
34
+ <div class="nas-picker-content" :aria-busy="busy" :inert="busy"><FileBrowser v-if="open" :provider="provider" :locale="locale" :mode="mode" @selected="selected=$event" /></div>
35
+ <template #footer><Button variant="secondary" :disabled="busy" @click="close">{{ copy.cancel }}</Button><Button variant="primary" :disabled="!selected||busy||!!destination&&mode!=='folder'" @click="confirm">{{ copy.confirm }}</Button></template>
19
36
  </Dialog>
20
37
  </template>
21
38
  <style scoped>
22
39
  .nas-picker-content { max-height: 65vh; overflow: auto; }
40
+ .save-message {--ui-text-secondary:var(--ui-text);}
41
+ .save-consent {color:var(--ui-text);margin-block:0 var(--ui-space-4,16px);}
23
42
  </style>
@@ -0,0 +1,48 @@
1
+ // @vitest-environment jsdom
2
+ import {afterEach,expect,test,vi} from 'vitest'
3
+ import {createApp,h,nextTick,ref} from 'vue'
4
+ import {AppRoot,ConfigProvider} from '@synopackageland/ui'
5
+ import NasPicker from './NasPicker.vue'
6
+ import {createNasProvider} from './provider'
7
+ import {nasCopy} from './locale'
8
+ const cleanup:Array<()=>void>=[]
9
+ afterEach(()=>cleanup.splice(0).forEach(fn=>fn()))
10
+ async function settle(){for(let i=0;i<30;i++){await Promise.resolve();await nextTick()}}
11
+ const grant={id:'d1',key:'save',path:'/home',username:'normal1',lifetime:'until-revoked' as const}
12
+ function fixture(selectDestination:any,mode:'folder'|'file'='folder'){
13
+ const root=document.createElement('div');document.body.append(root)
14
+ const selected=vi.fn(),authorized=vi.fn(),open=ref(true)
15
+ const provider=createNasProvider({call:vi.fn(async()=>({shares:[{name:'home',path:'/home',isdir:true}],offset:0,total:1})) as any})
16
+ const app=createApp({render:()=>h(ConfigProvider,{locale:'en'},()=>h(AppRoot,{},()=>h(NasPicker,{provider,locale:'en',mode,open:open.value,destination:{key:'save',selectDestination},onSelected:selected,onAuthorized:authorized,'onUpdate:open':v=>open.value=v})))})
17
+ app.config.idPrefix='destination-test';app.mount(root)
18
+ cleanup.push(()=>{app.unmount();provider.dispose();root.remove()})
19
+ return {root,open,selected,authorized,app}
20
+ }
21
+ function button(root:HTMLElement,label:string){const b=Array.from(root.querySelectorAll('button')).find(n=>n.textContent?.trim()===label||n.getAttribute('aria-label')===label);expect(b,label).toBeTruthy();return b!}
22
+ async function select(root:HTMLElement){await settle();button(root,'Select home').click();await settle();button(root,nasCopy('en').confirm).click();await settle()}
23
+ test('destination confirmation authorizes once with its manifest key, without a second consent dialog',async()=>{
24
+ const call=vi.fn(async()=>grant),f=fixture(call);await settle()
25
+ expect(f.root.textContent).toContain('after you sign out')
26
+ await select(f.root)
27
+ expect(call).toHaveBeenCalledExactlyOnceWith({key:'save',path:'/home'})
28
+ expect(f.authorized).toHaveBeenCalledExactlyOnceWith(grant)
29
+ expect(f.selected).not.toHaveBeenCalled();expect(f.open.value).toBe(false)
30
+ })
31
+ test('a rejected write/session check keeps the picker open and never emits a path or a grant',async()=>{
32
+ const f=fixture(vi.fn(async()=>{throw {code:'PERMISSION_DENIED',message:'secret SID'}}));await select(f.root)
33
+ expect(f.open.value).toBe(true);expect(f.selected).not.toHaveBeenCalled();expect(f.authorized).not.toHaveBeenCalled()
34
+ expect(f.root.querySelector('[role=alert]')?.textContent).toContain('permission')
35
+ expect(f.root.textContent).not.toContain('secret SID')
36
+ })
37
+ test('only folder destinations can authorize; a malformed grant is never reported as successful',async()=>{
38
+ const call=vi.fn(async()=>({...grant,path:'/elsewhere'})),f=fixture(call);await select(f.root)
39
+ expect(f.open.value).toBe(true);expect(f.authorized).not.toHaveBeenCalled()
40
+ const fileCall=vi.fn(async()=>grant),file=fixture(fileCall,'file');await settle()
41
+ expect(button(file.root,nasCopy('en').confirm).disabled).toBe(true);expect(fileCall).not.toHaveBeenCalled()
42
+ })
43
+ test('pending authorization prevents duplicate confirmation and ignores a late result after unmount',async()=>{
44
+ let resolve!:(value:typeof grant)=>void
45
+ const call=vi.fn(()=>new Promise(r=>resolve=r)),f=fixture(call);await select(f.root)
46
+ expect(button(f.root,nasCopy('en').confirm).disabled).toBe(true)
47
+ f.app.unmount();resolve(grant);await settle();expect(f.authorized).not.toHaveBeenCalled()
48
+ })
@@ -37,5 +37,5 @@
37
37
  "download": "Herunterladen",
38
38
  "uploaded": "Datei hochgeladen.",
39
39
  "errorDSM": "Melden Sie sich unter diesem Hostnamen bei DSM an, um auf NAS-Dateien zuzugreifen. Eine App-Anmeldung allein erlaubt keinen Zugriff auf File Station.",
40
- "errorUploadSize": "Wählen Sie eine Datei mit höchstens 16 GiB."
40
+ "errorUploadSize": "Wählen Sie eine Datei mit höchstens 16 GB aus."
41
41
  }
@@ -37,5 +37,5 @@
37
37
  "download": "Download",
38
38
  "uploaded": "File uploaded.",
39
39
  "errorDSM": "Sign in to DSM on this hostname to access NAS files. An App login alone cannot access File Station.",
40
- "errorUploadSize": "Choose one file up to 16 GiB."
40
+ "errorUploadSize": "Choose one file up to 16 GB."
41
41
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "title": "Carpetas NAS — File Station",
3
- "ownPermissions": "Las operaciones usan tu sesión DSM y tus permisos actuales de File Station.",
3
+ "ownPermissions": "Las operaciones usan su sesión DSM y sus permisos actuales de File Station.",
4
4
  "choose": "Elegir carpeta",
5
5
  "confirm": "Confirmar selección",
6
6
  "refresh": "Actualizar carpetas",
@@ -14,15 +14,15 @@
14
14
  "cancel": "Cancelar",
15
15
  "close": "Cerrar",
16
16
  "loadMore": "Cargar más",
17
- "errorSession": "La sesión DSM caducó. Inicia sesión en DSM y actualiza las carpetas.",
17
+ "errorSession": "La sesión DSM caducó. Inicie sesión en DSM y actualice las carpetas.",
18
18
  "errorDenied": "No tiene permiso para acceder a este archivo o carpeta. Elija otra carpeta.",
19
- "errorNotFound": "El archivo o la carpeta ya no existe. Actualiza la lista.",
20
- "errorConflict": "Ya existe un archivo o carpeta con ese nombre. Usa otro nombre.",
21
- "errorUncertain": "La operación puede haber terminado. Actualiza las selecciones o el destino y comprueba el resultado antes de enviarla de nuevo.",
22
- "errorInvalid": "Carpeta, nombre o solicitud inválidos. Revisa los datos.",
23
- "errorUnavailable": "File Station no está disponible o falta el adaptador de sesión. Actualiza más tarde.",
24
- "errorCanceled": "Solicitud cancelada. Actualiza antes de continuar.",
25
- "errorTimeout": "La solicitud agotó el tiempo. Actualiza la lista antes de continuar.",
19
+ "errorNotFound": "El archivo o la carpeta ya no existe. Actualice la lista.",
20
+ "errorConflict": "Ya existe un archivo o carpeta con ese nombre. Use otro nombre.",
21
+ "errorUncertain": "La operación puede haber terminado. Actualice las selecciones o el destino y compruebe el resultado antes de enviarla de nuevo.",
22
+ "errorInvalid": "Carpeta, nombre o solicitud no válidos. Revise los datos.",
23
+ "errorUnavailable": "File Station no está disponible o falta el adaptador de sesión. Actualice más tarde.",
24
+ "errorCanceled": "Solicitud cancelada. Actualice antes de continuar.",
25
+ "errorTimeout": "La solicitud agotó el tiempo. Actualice la lista antes de continuar.",
26
26
  "metadata": "Metadatos",
27
27
  "fileKind": "Archivo",
28
28
  "directoryKind": "Carpeta",
@@ -37,5 +37,5 @@
37
37
  "download": "Descargar",
38
38
  "uploaded": "Archivo subido.",
39
39
  "errorDSM": "Inicie sesión en DSM con este nombre de host para acceder a los archivos NAS. El inicio de sesión en la App por sí solo no permite usar File Station.",
40
- "errorUploadSize": "Seleccione un archivo de hasta 16 GiB."
40
+ "errorUploadSize": "Seleccione un archivo de hasta 16 GB."
41
41
  }
@@ -37,5 +37,5 @@
37
37
  "download": "Télécharger",
38
38
  "uploaded": "Fichier téléversé.",
39
39
  "errorDSM": "Connectez-vous à DSM sur ce nom d’hôte pour accéder aux fichiers NAS. La connexion à l’App seule ne permet pas d’utiliser File Station.",
40
- "errorUploadSize": "Choisissez un fichier de 16 GiB maximum."
40
+ "errorUploadSize": "Choisissez un fichier de 16 GB maximum."
41
41
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "title": "Cartelle NAS — File Station",
3
- "ownPermissions": "Le operazioni usano la tua sessione DSM e i permessi File Station attuali.",
3
+ "ownPermissions": "Le operazioni usano la sessione DSM corrente e i relativi permessi File Station.",
4
4
  "choose": "Scegli cartella",
5
5
  "confirm": "Conferma selezione",
6
6
  "refresh": "Aggiorna cartelle",
@@ -14,15 +14,15 @@
14
14
  "cancel": "Annulla",
15
15
  "close": "Chiudi",
16
16
  "loadMore": "Carica altro",
17
- "errorSession": "Sessione DSM scaduta. Accedi di nuovo a DSM e aggiorna le cartelle.",
18
- "errorDenied": "Non hai il permesso di accedere a questo file o cartella. Scegli un’altra cartella.",
19
- "errorNotFound": "Il file o la cartella non esiste più. Aggiorna l’elenco.",
20
- "errorConflict": "Esiste già un file o una cartella con questo nome. Scegli un altro nome.",
21
- "errorUncertain": "L’operazione potrebbe essere completata. Aggiorna selezioni o destinazione e controlla il risultato prima di inviarla di nuovo.",
22
- "errorInvalid": "Cartella, nome o richiesta non validi. Controlla i dati.",
23
- "errorUnavailable": "File Station non disponibile o adattatore di sessione mancante. Aggiorna più tardi.",
24
- "errorCanceled": "Richiesta annullata. Aggiorna prima di continuare.",
25
- "errorTimeout": "Tempo scaduto. Aggiorna l’elenco prima di continuare.",
17
+ "errorSession": "Sessione DSM scaduta. Accedere di nuovo a DSM e aggiornare le cartelle.",
18
+ "errorDenied": "Nessun permesso di accesso a questo file o cartella. Scegliere un’altra cartella.",
19
+ "errorNotFound": "Il file o la cartella non esiste più. Aggiornare l’elenco.",
20
+ "errorConflict": "Esiste già un file o una cartella con questo nome. Scegliere un altro nome.",
21
+ "errorUncertain": "L’operazione potrebbe essere stata completata. Aggiornare selezioni o destinazione e controllare il risultato prima di inviarla di nuovo.",
22
+ "errorInvalid": "Cartella, nome o richiesta non validi. Controllare i dati.",
23
+ "errorUnavailable": "File Station non disponibile o adattatore di sessione mancante. Aggiornare più tardi.",
24
+ "errorCanceled": "Richiesta annullata. Aggiornare prima di continuare.",
25
+ "errorTimeout": "Tempo scaduto. Aggiornare l’elenco prima di continuare.",
26
26
  "metadata": "Metadati",
27
27
  "fileKind": "File",
28
28
  "directoryKind": "Cartella",
@@ -36,6 +36,6 @@
36
36
  "upload": "Carica",
37
37
  "download": "Scarica",
38
38
  "uploaded": "File caricato.",
39
- "errorDSM": "Accedi a DSM con questo nome host per accedere ai file NAS. Il solo accesso all’App non consente di usare File Station.",
40
- "errorUploadSize": "Seleziona un file fino a 16 GiB."
39
+ "errorDSM": "Accedere a DSM con questo nome host per accedere ai file NAS. Il solo accesso all’App non consente di usare File Station.",
40
+ "errorUploadSize": "Selezionare un file fino a 16 GB."
41
41
  }
@@ -1,12 +1,12 @@
1
1
  {
2
- "title": "NAS フォルダー — File Station",
2
+ "title": "NAS フォルダ — File Station",
3
3
  "ownPermissions": "自分の DSM セッションと現在の File Station 権限で操作します。",
4
- "choose": "フォルダーを選択",
4
+ "choose": "フォルダを選択",
5
5
  "confirm": "選択を確定",
6
- "refresh": "フォルダーを更新",
6
+ "refresh": "フォルダを最新の情報に更新",
7
7
  "loading": "読み込み中…",
8
- "emptyFolder": "空のフォルダーです。",
9
- "roots": "フォルダー",
8
+ "emptyFolder": "空のフォルダです。",
9
+ "roots": "フォルダ",
10
10
  "back": "戻る",
11
11
  "select": "{name} を選択",
12
12
  "open": "{name} を開く",
@@ -14,18 +14,18 @@
14
14
  "cancel": "キャンセル",
15
15
  "close": "閉じる",
16
16
  "loadMore": "さらに読み込む",
17
- "errorSession": "DSM セッションが期限切れです。DSM に再ログインし、フォルダーを更新してください。",
17
+ "errorSession": "DSM セッションが期限切れです。DSM に再ログインし、フォルダを最新の情報に更新してください。",
18
18
  "errorDenied": "このファイルまたはフォルダにアクセスする権限がありません。別のフォルダを選択してください。",
19
- "errorNotFound": "ファイルまたはフォルダーがありません。一覧を更新してください。",
20
- "errorConflict": "同名のファイルまたはフォルダーがあります。別の名前を指定してください。",
21
- "errorUncertain": "操作が完了した可能性があります。再送信する前に選択または保存先を更新し、結果を確認してください。",
22
- "errorInvalid": "フォルダー、ファイル名またはリクエストが無効です。入力を確認してください。",
23
- "errorUnavailable": "File Station が利用できないか、このパッケージにセッション adapter がありません。後で更新してください。",
24
- "errorCanceled": "リクエストをキャンセルしました。更新してから続けてください。",
25
- "errorTimeout": "リクエストがタイムアウトしました。一覧を更新してください。",
19
+ "errorNotFound": "ファイルまたはフォルダがありません。一覧を最新の情報に更新してください。",
20
+ "errorConflict": "同名のファイルまたはフォルダがあります。別の名前を指定してください。",
21
+ "errorUncertain": "操作が完了した可能性があります。再送信する前に選択または保存先を最新の情報に更新し、結果を確認してください。",
22
+ "errorInvalid": "フォルダ、ファイル名またはリクエストが無効です。入力を確認してください。",
23
+ "errorUnavailable": "File Station が利用できないか、このパッケージにセッション adapter がありません。後で最新の情報に更新してください。",
24
+ "errorCanceled": "リクエストをキャンセルしました。最新の情報に更新してから続けてください。",
25
+ "errorTimeout": "リクエストがタイムアウトしました。一覧を最新の情報に更新してください。",
26
26
  "metadata": "情報",
27
27
  "fileKind": "ファイル",
28
- "directoryKind": "フォルダー",
28
+ "directoryKind": "フォルダ",
29
29
  "nameColumn": "名前",
30
30
  "kindColumn": "種類",
31
31
  "sizeColumn": "バイト",
@@ -37,5 +37,5 @@
37
37
  "download": "ダウンロード",
38
38
  "uploaded": "ファイルをアップロードしました。",
39
39
  "errorDSM": "NAS ファイルを利用するには同じホスト名で DSM にサインインしてください。App のログインだけでは File Station を利用できません。",
40
- "errorUploadSize": "16 GiB 以下のファイルを 1 個選択してください。"
40
+ "errorUploadSize": "16 GB 以下のファイルを 1 つ選択してください。"
41
41
  }
@@ -12,17 +12,17 @@
12
12
  "open": "{name} 열기",
13
13
  "selected": "선택됨: {name}",
14
14
  "cancel": "취소",
15
- "close": "닫기",
15
+ "close": "종료",
16
16
  "loadMore": "더 불러오기",
17
- "errorSession": "DSM 세션이 만료되었습니다. DSM에 다시 로그인한 후 폴더를 새로 고치세요.",
18
- "errorDenied": "이 파일 또는 폴더에 접근할 권한이 없습니다. 다른 폴더를 선택하세요.",
19
- "errorNotFound": "파일 또는 폴더가 없습니다. 목록을 새로 고치세요.",
20
- "errorConflict": "같은 이름의 파일 또는 폴더가 있습니다. 다른 이름을 사용하세요.",
21
- "errorUncertain": "작업이 완료되었을 수 있습니다. 다시 제출하기 전에 선택 또는 대상 폴더를 새로 고쳐 결과를 확인하세요.",
22
- "errorInvalid": "폴더, 파일 이름 또는 요청이 잘못되었습니다. 입력을 확인하세요.",
23
- "errorUnavailable": "File Station을 사용할 수 없거나 패키지에 세션 adapter가 없습니다. 나중에 새로 고치세요.",
24
- "errorCanceled": "요청이 취소되었습니다. 새로 고친 후 계속하세요.",
25
- "errorTimeout": "요청 시간이 초과되었습니다. 목록을 새로 고치세요.",
17
+ "errorSession": "DSM 세션이 만료되었습니다. DSM에 다시 로그인한 후 폴더를 새로 고치십시오.",
18
+ "errorDenied": "이 파일 또는 폴더에 접근할 권한이 없습니다. 다른 폴더를 선택하십시오.",
19
+ "errorNotFound": "파일 또는 폴더가 없습니다. 목록을 새로 고치십시오.",
20
+ "errorConflict": "같은 이름의 파일 또는 폴더가 있습니다. 다른 이름을 사용하십시오.",
21
+ "errorUncertain": "작업이 완료되었을 수 있습니다. 다시 제출하기 전에 선택 또는 대상 폴더를 새로 고쳐 결과를 확인하십시오.",
22
+ "errorInvalid": "폴더, 파일 이름 또는 요청이 잘못되었습니다. 입력을 확인하십시오.",
23
+ "errorUnavailable": "File Station을 사용할 수 없거나 패키지에 세션 adapter가 없습니다. 나중에 새로 고치십시오.",
24
+ "errorCanceled": "요청이 취소되었습니다. 새로 고친 후 계속하십시오.",
25
+ "errorTimeout": "요청 시간이 초과되었습니다. 목록을 새로 고치십시오.",
26
26
  "metadata": "정보",
27
27
  "fileKind": "파일",
28
28
  "directoryKind": "폴더",
@@ -36,6 +36,6 @@
36
36
  "upload": "업로드",
37
37
  "download": "다운로드",
38
38
  "uploaded": "파일을 업로드했습니다.",
39
- "errorDSM": "NAS 파일에 접근하려면 같은 호스트 이름에서 DSM에 로그인하세요. App 로그인만으로는 File Station을 사용할 수 없습니다.",
40
- "errorUploadSize": "16 GiB 이하의 파일 하나를 선택하세요."
39
+ "errorDSM": "NAS 파일에 접근하려면 같은 호스트 이름에서 DSM에 로그인하십시오. App 로그인만으로는 File Station을 사용할 수 없습니다.",
40
+ "errorUploadSize": "16 GB 이하의 파일 하나를 선택하십시오."
41
41
  }
@@ -37,5 +37,5 @@
37
37
  "download": "下载",
38
38
  "uploaded": "文件已上传。",
39
39
  "errorDSM": "请在同一主机名登录 DSM,以访问 NAS 文件。只有 App 登录无法使用 File Station。",
40
- "errorUploadSize": "请选择一个不超过 16 GiB 的文件。"
40
+ "errorUploadSize": "请选择一个不超过 16 GB 的文件。"
41
41
  }
@@ -37,5 +37,5 @@
37
37
  "download": "下載",
38
38
  "uploaded": "檔案已上傳。",
39
39
  "errorDSM": "請在同一主機名稱登入 DSM,以存取 NAS 檔案。只有 App 登入無法使用 File Station。",
40
- "errorUploadSize": "請選擇一個不超過 16 GiB 的檔案。"
40
+ "errorUploadSize": "請選擇一個不超過 16 GB 的檔案。"
41
41
  }
@@ -0,0 +1,39 @@
1
+ <script setup lang="ts">
2
+ import {onBeforeUnmount,onMounted,ref} from 'vue'
3
+ import {Button,Callout,Form,FormActions,FormItem,Input,Link,SettingsSection} from '@synopackageland/ui'
4
+ import type {PortalAccess,PortalStatus} from '../context'
5
+ // SDK text in DSM's language comes with ctx.portal; DSM decides who may change the alias.
6
+ const props=defineProps<{portal:PortalAccess}>()
7
+ const m=props.portal.messages
8
+ const status=ref<PortalStatus>(),alias=ref(''),busy=ref(false),error=ref('')
9
+ let disposed=false
10
+ function show(next:PortalStatus){if(disposed)return;status.value=next;alias.value=next.alias||next.defaultAlias}
11
+ async function run(change:()=>Promise<PortalStatus>){
12
+ if(busy.value)return
13
+ busy.value=true;error.value=''
14
+ try{show(await change())}
15
+ catch(e){if(!disposed)error.value=m[(e as {code?:string})?.code||'']||m.portal_unavailable}
16
+ finally{if(!disposed)busy.value=false}
17
+ }
18
+ onMounted(()=>void props.portal.status().then(show))
19
+ onBeforeUnmount(()=>{disposed=true})
20
+ </script>
21
+ <template>
22
+ <SettingsSection v-if="status" :title="m.title" :collapsible="false" :aria-busy="busy">
23
+ <p v-if="status.state==='active'">{{ m.link }} <Link :href="status.url" external>{{ status.url }}</Link></p>
24
+ <template v-if="status.canManage">
25
+ <p v-if="status.state!=='active'">{{ m.inactive }}</p>
26
+ <Form @submit.prevent="run(()=>portal.apply(alias))">
27
+ <FormItem :label="m.alias" label-for="portal-alias"><Input id="portal-alias" v-model="alias" maxlength="64" autocomplete="off" :disabled="busy" /></FormItem>
28
+ <FormActions>
29
+ <Button type="submit" variant="primary" :disabled="busy">{{ m.apply }}</Button>
30
+ <Button v-if="status.state==='active'" variant="secondary" :disabled="busy" @click="run(()=>portal.disable())">{{ m.disable }}</Button>
31
+ </FormActions>
32
+ </Form>
33
+ <Button variant="secondary" @click="portal.openControlPanel()">{{ m.advanced }}</Button>
34
+ </template>
35
+ <Button v-else-if="status.controlPanel" variant="secondary" @click="portal.openControlPanel()">{{ m.controlPanel }}</Button>
36
+ <p v-else-if="status.state!=='active'">{{ m.askAdmin }}</p>
37
+ <Callout v-if="error" tone="danger"><span role="alert">{{ error }}</span></Callout>
38
+ </SettingsSection>
39
+ </template>
@@ -1,4 +1,4 @@
1
1
  {
2
- "status": "État",
2
+ "status": "Statut",
3
3
  "background": "Tâches en arrière-plan"
4
4
  }
@@ -1,4 +1,4 @@
1
1
  {
2
- "status": "ステータス",
2
+ "status": "状態",
3
3
  "background": "バックグラウンドジョブ"
4
4
  }