@synopackageland/cli 0.4.0 → 0.4.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.
Files changed (438) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +37 -0
  3. package/dist/build-spk/generator.js +3 -0
  4. package/dist/build-spk/notices.d.ts +5 -0
  5. package/dist/build-spk/notices.js +60 -0
  6. package/dist/cli.js +9 -2
  7. package/dist/error-registry.js +20 -0
  8. package/dist/init.d.ts +4 -0
  9. package/dist/init.js +20 -12
  10. package/dist/standalone/build.js +3 -1
  11. package/dist/standalone/daemon.d.ts +23 -0
  12. package/dist/standalone/daemon.js +114 -0
  13. package/dist/standalone/dsm-window.d.ts +1 -1
  14. package/dist/standalone/dsm-window.js +50 -10
  15. package/dist/standalone/helper-inventory.d.ts +16 -0
  16. package/dist/standalone/helper-inventory.js +2 -0
  17. package/dist/standalone/helper.d.ts +2 -12
  18. package/dist/standalone/helper.js +8 -7
  19. package/dist/standalone/host-adapter.d.ts +5 -0
  20. package/dist/standalone/host-adapter.js +148 -0
  21. package/dist/standalone/host-platform.d.ts +13 -0
  22. package/dist/standalone/host-platform.js +42 -0
  23. package/dist/standalone/host-types.d.ts +49 -0
  24. package/dist/standalone/host-types.js +1 -0
  25. package/dist/standalone/inspect-helper.d.ts +6 -0
  26. package/dist/standalone/inspect-helper.js +88 -0
  27. package/dist/standalone/inspect-spk.d.ts +2 -0
  28. package/dist/standalone/inspect-spk.js +49 -0
  29. package/dist/standalone/lifecycle-helper.d.ts +2 -0
  30. package/dist/standalone/lifecycle-helper.js +12 -0
  31. package/dist/standalone/lifecycle.d.ts +3 -0
  32. package/dist/standalone/lifecycle.js +53 -0
  33. package/dist/standalone/manifest.d.ts +2 -0
  34. package/dist/standalone/manifest.js +4 -1
  35. package/dist/standalone/reopen-events.d.ts +2 -0
  36. package/dist/standalone/reopen-events.js +28 -0
  37. package/dist/standalone/root-messages.js +9 -0
  38. package/dist/standalone/root-window.d.ts +4 -3
  39. package/dist/standalone/root-window.js +17 -5
  40. package/dist/standalone/spk.d.ts +4 -3
  41. package/dist/standalone/spk.js +20 -33
  42. package/dist/template-paths.d.ts +2 -0
  43. package/dist/template-paths.js +9 -0
  44. package/dist/templates/_daemon/fixture_linux_test.go +15 -0
  45. package/dist/templates/_daemon/fixture_other_test.go +7 -0
  46. package/dist/templates/_daemon/go.mod +3 -0
  47. package/dist/templates/_daemon/main.go +608 -0
  48. package/dist/templates/_daemon/main_test.go +242 -0
  49. package/dist/templates/_daemon/process_linux.go +55 -0
  50. package/dist/templates/_daemon/process_linux_test.go +161 -0
  51. package/dist/templates/_daemon/process_other.go +14 -0
  52. package/dist/templates/_daemon/testdata/child.go +41 -0
  53. package/dist/templates/_shared/GO-LICENSE +27 -0
  54. package/dist/templates/_shared/GO-PATENTS +22 -0
  55. package/dist/templates/_shared/LICENSES/TEMPLATE.txt +21 -0
  56. package/dist/templates/_shared/notice-overrides/index.json +14 -0
  57. package/dist/templates/_shared/notice-overrides/utils-0.4.2-LICENSE +21 -0
  58. package/dist/templates/_shared/notice-overrides/utils-0.5.0-LICENSE +21 -0
  59. package/dist/templates/_shared/third-party-notices.mjs +51 -0
  60. package/dist/templates/native-go/README.md +57 -1
  61. package/dist/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +59 -0
  62. package/dist/templates/native-go/backend/cmd/dsm-readonly-probe/main_linux.go +46 -0
  63. package/dist/templates/native-go/backend/go.mod +4 -0
  64. package/dist/templates/native-go/backend/go.sum +4 -0
  65. package/dist/templates/native-go/backend/internal/api/binary.go +154 -0
  66. package/dist/templates/native-go/backend/internal/api/binary_test.go +165 -0
  67. package/dist/templates/native-go/backend/internal/api/registry.go +14 -4
  68. package/dist/templates/native-go/backend/internal/api/server.go +4 -0
  69. package/dist/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +121 -0
  70. package/dist/templates/native-go/backend/internal/app/nas_refusal_test.go +46 -0
  71. package/dist/templates/native-go/backend/internal/app/routes.go +11 -0
  72. package/dist/templates/native-go/backend/internal/app/routes_test.go +10 -5
  73. package/dist/templates/native-go/backend/internal/dsmprobe/collector_linux.go +335 -0
  74. package/dist/templates/native-go/backend/internal/dsmprobe/collector_linux_test.go +41 -0
  75. package/dist/templates/native-go/backend/internal/dsmprobe/protocol.go +179 -0
  76. package/dist/templates/native-go/backend/internal/dsmprobe/protocol_test.go +29 -0
  77. package/dist/templates/native-go/backend/internal/helper/cohort.go +393 -0
  78. package/dist/templates/native-go/backend/internal/helper/cohort_publication.go +18 -0
  79. package/dist/templates/native-go/backend/internal/helper/cohort_publication_test.go +105 -0
  80. package/dist/templates/native-go/backend/internal/helper/cohort_test.go +372 -0
  81. package/dist/templates/native-go/backend/internal/helper/control.go +226 -21
  82. package/dist/templates/native-go/backend/internal/helper/control_test.go +10 -2
  83. package/dist/templates/native-go/backend/internal/helper/data_contract.go +242 -0
  84. package/dist/templates/native-go/backend/internal/helper/data_contract_test.go +51 -0
  85. package/dist/templates/native-go/backend/internal/helper/data_decode.go +184 -0
  86. package/dist/templates/native-go/backend/internal/helper/data_decode_pointer_test.go +30 -0
  87. package/dist/templates/native-go/backend/internal/helper/data_protocol.go +416 -0
  88. package/dist/templates/native-go/backend/internal/helper/data_protocol_test.go +449 -0
  89. package/dist/templates/native-go/backend/internal/helper/dsm_acl_linux.go +139 -0
  90. package/dist/templates/native-go/backend/internal/helper/dsm_acl_linux_test.go +121 -0
  91. package/dist/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux.go +95 -0
  92. package/dist/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux_test.go +56 -0
  93. package/dist/templates/native-go/backend/internal/helper/dsm_bridge_linux.go +144 -0
  94. package/dist/templates/native-go/backend/internal/helper/dsm_bridge_linux_test.go +89 -0
  95. package/dist/templates/native-go/backend/internal/helper/dsm_home_linux.go +107 -0
  96. package/dist/templates/native-go/backend/internal/helper/dsm_home_linux_test.go +82 -0
  97. package/dist/templates/native-go/backend/internal/helper/dsm_probe_transport_linux.go +151 -0
  98. package/dist/templates/native-go/backend/internal/helper/dsm_probe_transport_linux_test.go +66 -0
  99. package/dist/templates/native-go/backend/internal/helper/grant_authority.go +516 -0
  100. package/dist/templates/native-go/backend/internal/helper/grant_authority_contract.go +88 -0
  101. package/dist/templates/native-go/backend/internal/helper/grant_authority_test.go +510 -0
  102. package/dist/templates/native-go/backend/internal/helper/grant_cohort.go +389 -0
  103. package/dist/templates/native-go/backend/internal/helper/grant_cohort_test.go +239 -0
  104. package/dist/templates/native-go/backend/internal/helper/grant_delivery.go +49 -0
  105. package/dist/templates/native-go/backend/internal/helper/grant_delivery_methods.go +273 -0
  106. package/dist/templates/native-go/backend/internal/helper/grant_delivery_test.go +322 -0
  107. package/dist/templates/native-go/backend/internal/helper/grant_operation_contract.go +47 -0
  108. package/dist/templates/native-go/backend/internal/helper/grant_readonly_test.go +180 -0
  109. package/dist/templates/native-go/backend/internal/helper/grant_repository_linux.go +415 -0
  110. package/dist/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +468 -0
  111. package/dist/templates/native-go/backend/internal/helper/grant_rpc.go +147 -0
  112. package/dist/templates/native-go/backend/internal/helper/grant_rpc_test.go +51 -0
  113. package/dist/templates/native-go/backend/internal/helper/grant_snapshot.go +75 -0
  114. package/dist/templates/native-go/backend/internal/helper/grant_supervisor_linux.go +134 -0
  115. package/dist/templates/native-go/backend/internal/helper/grant_supervisor_linux_test.go +254 -0
  116. package/dist/templates/native-go/backend/internal/helper/lease.go +112 -0
  117. package/dist/templates/native-go/backend/internal/helper/lease_linux.go +44 -0
  118. package/dist/templates/native-go/backend/internal/helper/lease_other.go +8 -0
  119. package/dist/templates/native-go/backend/internal/helper/lifecycle.go +234 -0
  120. package/dist/templates/native-go/backend/internal/helper/lifecycle_test.go +473 -0
  121. package/dist/templates/native-go/backend/internal/helper/managed_pilot.go +284 -0
  122. package/dist/templates/native-go/backend/internal/helper/managed_pilot_repository_linux.go +74 -0
  123. package/dist/templates/native-go/backend/internal/helper/managed_pilot_repository_linux_test.go +40 -0
  124. package/dist/templates/native-go/backend/internal/helper/managed_pilot_test.go +210 -0
  125. package/dist/templates/native-go/backend/internal/helper/nas_shipped_refusal_linux_test.go +97 -0
  126. package/dist/templates/native-go/backend/internal/helper/native_discovery.go +79 -0
  127. package/dist/templates/native-go/backend/internal/helper/native_identity.go +89 -0
  128. package/dist/templates/native-go/backend/internal/helper/native_provider.go +159 -0
  129. package/dist/templates/native-go/backend/internal/helper/native_provider_test.go +421 -0
  130. package/dist/templates/native-go/backend/internal/helper/observation.go +204 -0
  131. package/dist/templates/native-go/backend/internal/helper/observation_health_test.go +115 -0
  132. package/dist/templates/native-go/backend/internal/helper/observation_reload_budget_test.go +117 -0
  133. package/dist/templates/native-go/backend/internal/helper/observation_test.go +196 -0
  134. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic.go +109 -0
  135. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux.go +76 -0
  136. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +124 -0
  137. package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_test.go +98 -0
  138. package/dist/templates/native-go/backend/internal/helper/operation_bootstrap_linux.go +193 -0
  139. package/dist/templates/native-go/backend/internal/helper/operation_credentials_linux.go +56 -0
  140. package/dist/templates/native-go/backend/internal/helper/operation_linux.go +480 -0
  141. package/dist/templates/native-go/backend/internal/helper/operation_linux_test.go +528 -0
  142. package/dist/templates/native-go/backend/internal/helper/process_linux.go +11 -1
  143. package/dist/templates/native-go/backend/internal/helper/publication_test.go +178 -0
  144. package/dist/templates/native-go/backend/internal/helper/read_stream_cohort_linux_test.go +156 -0
  145. package/dist/templates/native-go/backend/internal/helper/read_transfer.go +40 -0
  146. package/dist/templates/native-go/backend/internal/helper/read_transfer_linux.go +109 -0
  147. package/dist/templates/native-go/backend/internal/helper/read_transfer_linux_test.go +118 -0
  148. package/dist/templates/native-go/backend/internal/helper/read_transfer_test.go +177 -0
  149. package/dist/templates/native-go/backend/internal/helper/readonly.go +105 -0
  150. package/dist/templates/native-go/backend/internal/helper/readonly_admission.go +85 -0
  151. package/dist/templates/native-go/backend/internal/helper/readonly_cohort_linux_test.go +253 -0
  152. package/dist/templates/native-go/backend/internal/helper/readonly_linux_test.go +378 -0
  153. package/dist/templates/native-go/backend/internal/helper/readonly_mount_linux.go +65 -0
  154. package/dist/templates/native-go/backend/internal/helper/readonly_mount_proxy_linux.go +113 -0
  155. package/dist/templates/native-go/backend/internal/helper/readonly_operations_linux.go +168 -0
  156. package/dist/templates/native-go/backend/internal/helper/readonly_resolver_linux.go +241 -0
  157. package/dist/templates/native-go/backend/internal/helper/readonly_test.go +40 -0
  158. package/dist/templates/native-go/backend/internal/helper/relaxed_identity.go +252 -0
  159. package/dist/templates/native-go/backend/internal/helper/relaxed_identity_contract.go +105 -0
  160. package/dist/templates/native-go/backend/internal/helper/relaxed_identity_test.go +406 -0
  161. package/dist/templates/native-go/backend/internal/helper/relaxed_invalidation.go +200 -0
  162. package/dist/templates/native-go/backend/internal/helper/repair.go +132 -0
  163. package/dist/templates/native-go/backend/internal/helper/repair_test.go +271 -0
  164. package/dist/templates/native-go/backend/internal/helper/s1r_actor_acl_linux_test.go +303 -0
  165. package/dist/templates/native-go/backend/internal/helper/s1r_actor_fixture_linux_test.go +184 -0
  166. package/dist/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +231 -0
  167. package/dist/templates/native-go/backend/internal/helper/s1r_fixture_contract_linux_test.go +18 -0
  168. package/dist/templates/native-go/backend/internal/helper/server_linux.go +44 -3
  169. package/dist/templates/native-go/backend/internal/helper/status.go +74 -11
  170. package/dist/templates/native-go/backend/internal/helper/status_test.go +83 -0
  171. package/dist/templates/native-go/backend/internal/helper/supervision.go +28 -5
  172. package/dist/templates/native-go/backend/internal/helper/supervisor_frame.go +76 -0
  173. package/dist/templates/native-go/backend/internal/helper/supervisor_frame_linux_test.go +69 -0
  174. package/dist/templates/native-go/backend/internal/helper/supervisor_frame_test.go +107 -0
  175. package/dist/templates/native-go/backend/internal/helper/supervisor_linux.go +187 -16
  176. package/dist/templates/native-go/backend/internal/helper/supervisor_linux_test.go +618 -7
  177. package/dist/templates/native-go/backend/internal/helper/supervisor_socket_eof_test.go +74 -0
  178. package/dist/templates/native-go/backend/internal/helper/supervisor_socket_test.go +45 -0
  179. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/create.json +23 -0
  180. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/frames.json +67 -0
  181. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/grant-store.json +52 -0
  182. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/intent.json +20 -0
  183. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/list.json +20 -0
  184. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/publish.json +20 -0
  185. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/read.json +22 -0
  186. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/stat.json +22 -0
  187. package/dist/templates/native-go/backend/internal/helper/testdata/protocol2/write-stream.json +22 -0
  188. package/dist/templates/native-go/backend/internal/helper/unit_connection.go +75 -0
  189. package/dist/templates/native-go/backend/internal/helper/unit_connection_linux_test.go +135 -0
  190. package/dist/templates/native-go/backend/internal/helper/unit_connection_test.go +133 -0
  191. package/dist/templates/native-go/backend/internal/helper/unit_frame_test.go +32 -0
  192. package/dist/templates/native-go/backend/internal/helper/unit_linux.go +364 -0
  193. package/dist/templates/native-go/backend/internal/helper/unit_linux_test.go +46 -0
  194. package/dist/templates/native-go/backend/internal/helper/unit_mechanisms_linux_test.go +217 -0
  195. package/dist/templates/native-go/backend/internal/helper/unit_padding_linux_test.go +178 -0
  196. package/dist/templates/native-go/backend/internal/helper/unit_query_linux.go +111 -0
  197. package/dist/templates/native-go/backend/internal/helper/unit_reload_linux_test.go +372 -0
  198. package/dist/templates/native-go/backend/internal/helper/unit_reload_sequence_linux_test.go +232 -0
  199. package/dist/templates/native-go/backend/internal/helper/write.go +77 -0
  200. package/dist/templates/native-go/backend/internal/helper/write_admission.go +260 -0
  201. package/dist/templates/native-go/backend/internal/helper/write_admission_test.go +135 -0
  202. package/dist/templates/native-go/backend/internal/helper/write_cohort_linux_test.go +218 -0
  203. package/dist/templates/native-go/backend/internal/helper/write_files_linux.go +202 -0
  204. package/dist/templates/native-go/backend/internal/helper/write_files_linux_test.go +199 -0
  205. package/dist/templates/native-go/backend/internal/helper/write_intent_linux.go +116 -0
  206. package/dist/templates/native-go/backend/internal/helper/write_intent_linux_test.go +74 -0
  207. package/dist/templates/native-go/backend/internal/helper/write_operation_linux.go +245 -0
  208. package/dist/templates/native-go/backend/internal/helper/write_test.go +53 -0
  209. package/dist/templates/native-go/ui/app.js +8 -1
  210. package/dist/templates/native-go-better-auth/node/build.mjs +2 -0
  211. package/dist/templates/native-go-vue/README.md +115 -1
  212. package/dist/templates/native-go-vue/frontend/DESIGN.md +1 -1
  213. package/dist/templates/native-go-vue/frontend/package-lock.json +132 -229
  214. package/dist/templates/native-go-vue/frontend/package.json +1 -1
  215. package/dist/templates/native-go-vue/frontend/src/App.vue +33 -6
  216. package/dist/templates/native-go-vue/frontend/src/context.ts +41 -2
  217. package/dist/templates/native-go-vue/frontend/src/main.ts +4 -1
  218. package/dist/templates/native-go-vue/frontend/src/nas/NasGrantSettings.vue +74 -0
  219. package/dist/templates/native-go-vue/frontend/src/nas/NasPathPicker.vue +106 -0
  220. package/dist/templates/native-go-vue/frontend/src/nas/NasUnavailable.vue +20 -0
  221. package/dist/templates/native-go-vue/frontend/src/nas/i18n/de.json +74 -0
  222. package/dist/templates/native-go-vue/frontend/src/nas/i18n/en.json +74 -0
  223. package/dist/templates/native-go-vue/frontend/src/nas/i18n/es.json +74 -0
  224. package/dist/templates/native-go-vue/frontend/src/nas/i18n/fr.json +74 -0
  225. package/dist/templates/native-go-vue/frontend/src/nas/i18n/it.json +74 -0
  226. package/dist/templates/native-go-vue/frontend/src/nas/i18n/ja.json +74 -0
  227. package/dist/templates/native-go-vue/frontend/src/nas/i18n/ko.json +74 -0
  228. package/dist/templates/native-go-vue/frontend/src/nas/i18n/zh-CN.json +74 -0
  229. package/dist/templates/native-go-vue/frontend/src/nas/i18n/zh-TW.json +74 -0
  230. package/dist/templates/native-go-vue/frontend/src/nas/i18n.ts +38 -0
  231. package/dist/templates/native-go-vue/frontend/src/nas/mock-provider.ts +119 -0
  232. package/dist/templates/native-go-vue/frontend/src/nas/provider.ts +59 -0
  233. package/dist/templates/native-go-vue/frontend/src/nas/use-request.ts +27 -0
  234. package/dist/templates/native-go-vue/frontend/src/style.css +17 -0
  235. package/dist/templates/native-go-vue/frontend/test/apps.test.ts +44 -2
  236. package/dist/templates/native-go-vue/frontend/test/nas-provider.test.ts +81 -0
  237. package/dist/templates/native-go-vue/frontend/test/nas-request.test.ts +21 -0
  238. package/dist/templates/native-go-vue/frontend/test/nas-ui.test.ts +261 -0
  239. package/dist/templates/native-go-vue/frontend/tsconfig.json +1 -1
  240. package/dist/templates/native-go-vue/frontend/vite.config.ts +6 -4
  241. package/package.json +3 -2
  242. package/templates/_daemon/fixture_linux_test.go +15 -0
  243. package/templates/_daemon/fixture_other_test.go +7 -0
  244. package/templates/_daemon/go.mod +3 -0
  245. package/templates/_daemon/main.go +608 -0
  246. package/templates/_daemon/main_test.go +242 -0
  247. package/templates/_daemon/process_linux.go +55 -0
  248. package/templates/_daemon/process_linux_test.go +161 -0
  249. package/templates/_daemon/process_other.go +14 -0
  250. package/templates/_daemon/testdata/child.go +41 -0
  251. package/templates/_shared/GO-LICENSE +27 -0
  252. package/templates/_shared/GO-PATENTS +22 -0
  253. package/templates/_shared/LICENSES/TEMPLATE.txt +21 -0
  254. package/templates/_shared/notice-overrides/index.json +14 -0
  255. package/templates/_shared/notice-overrides/utils-0.4.2-LICENSE +21 -0
  256. package/templates/_shared/notice-overrides/utils-0.5.0-LICENSE +21 -0
  257. package/templates/_shared/third-party-notices.mjs +51 -0
  258. package/templates/native-go/README.md +57 -1
  259. package/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +59 -0
  260. package/templates/native-go/backend/cmd/dsm-readonly-probe/main_linux.go +46 -0
  261. package/templates/native-go/backend/go.mod +4 -0
  262. package/templates/native-go/backend/go.sum +4 -0
  263. package/templates/native-go/backend/internal/api/binary.go +154 -0
  264. package/templates/native-go/backend/internal/api/binary_test.go +165 -0
  265. package/templates/native-go/backend/internal/api/registry.go +14 -4
  266. package/templates/native-go/backend/internal/api/server.go +4 -0
  267. package/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +121 -0
  268. package/templates/native-go/backend/internal/app/nas_refusal_test.go +46 -0
  269. package/templates/native-go/backend/internal/app/routes.go +11 -0
  270. package/templates/native-go/backend/internal/app/routes_test.go +10 -5
  271. package/templates/native-go/backend/internal/dsmprobe/collector_linux.go +335 -0
  272. package/templates/native-go/backend/internal/dsmprobe/collector_linux_test.go +41 -0
  273. package/templates/native-go/backend/internal/dsmprobe/protocol.go +179 -0
  274. package/templates/native-go/backend/internal/dsmprobe/protocol_test.go +29 -0
  275. package/templates/native-go/backend/internal/helper/cohort.go +393 -0
  276. package/templates/native-go/backend/internal/helper/cohort_publication.go +18 -0
  277. package/templates/native-go/backend/internal/helper/cohort_publication_test.go +105 -0
  278. package/templates/native-go/backend/internal/helper/cohort_test.go +372 -0
  279. package/templates/native-go/backend/internal/helper/control.go +226 -21
  280. package/templates/native-go/backend/internal/helper/control_test.go +10 -2
  281. package/templates/native-go/backend/internal/helper/data_contract.go +242 -0
  282. package/templates/native-go/backend/internal/helper/data_contract_test.go +51 -0
  283. package/templates/native-go/backend/internal/helper/data_decode.go +184 -0
  284. package/templates/native-go/backend/internal/helper/data_decode_pointer_test.go +30 -0
  285. package/templates/native-go/backend/internal/helper/data_protocol.go +416 -0
  286. package/templates/native-go/backend/internal/helper/data_protocol_test.go +449 -0
  287. package/templates/native-go/backend/internal/helper/dsm_acl_linux.go +139 -0
  288. package/templates/native-go/backend/internal/helper/dsm_acl_linux_test.go +121 -0
  289. package/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux.go +95 -0
  290. package/templates/native-go/backend/internal/helper/dsm_acl_syscall_linux_test.go +56 -0
  291. package/templates/native-go/backend/internal/helper/dsm_bridge_linux.go +144 -0
  292. package/templates/native-go/backend/internal/helper/dsm_bridge_linux_test.go +89 -0
  293. package/templates/native-go/backend/internal/helper/dsm_home_linux.go +107 -0
  294. package/templates/native-go/backend/internal/helper/dsm_home_linux_test.go +82 -0
  295. package/templates/native-go/backend/internal/helper/dsm_probe_transport_linux.go +151 -0
  296. package/templates/native-go/backend/internal/helper/dsm_probe_transport_linux_test.go +66 -0
  297. package/templates/native-go/backend/internal/helper/grant_authority.go +516 -0
  298. package/templates/native-go/backend/internal/helper/grant_authority_contract.go +88 -0
  299. package/templates/native-go/backend/internal/helper/grant_authority_test.go +510 -0
  300. package/templates/native-go/backend/internal/helper/grant_cohort.go +389 -0
  301. package/templates/native-go/backend/internal/helper/grant_cohort_test.go +239 -0
  302. package/templates/native-go/backend/internal/helper/grant_delivery.go +49 -0
  303. package/templates/native-go/backend/internal/helper/grant_delivery_methods.go +273 -0
  304. package/templates/native-go/backend/internal/helper/grant_delivery_test.go +322 -0
  305. package/templates/native-go/backend/internal/helper/grant_operation_contract.go +47 -0
  306. package/templates/native-go/backend/internal/helper/grant_readonly_test.go +180 -0
  307. package/templates/native-go/backend/internal/helper/grant_repository_linux.go +415 -0
  308. package/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +468 -0
  309. package/templates/native-go/backend/internal/helper/grant_rpc.go +147 -0
  310. package/templates/native-go/backend/internal/helper/grant_rpc_test.go +51 -0
  311. package/templates/native-go/backend/internal/helper/grant_snapshot.go +75 -0
  312. package/templates/native-go/backend/internal/helper/grant_supervisor_linux.go +134 -0
  313. package/templates/native-go/backend/internal/helper/grant_supervisor_linux_test.go +254 -0
  314. package/templates/native-go/backend/internal/helper/lease.go +112 -0
  315. package/templates/native-go/backend/internal/helper/lease_linux.go +44 -0
  316. package/templates/native-go/backend/internal/helper/lease_other.go +8 -0
  317. package/templates/native-go/backend/internal/helper/lifecycle.go +234 -0
  318. package/templates/native-go/backend/internal/helper/lifecycle_test.go +473 -0
  319. package/templates/native-go/backend/internal/helper/managed_pilot.go +284 -0
  320. package/templates/native-go/backend/internal/helper/managed_pilot_repository_linux.go +74 -0
  321. package/templates/native-go/backend/internal/helper/managed_pilot_repository_linux_test.go +40 -0
  322. package/templates/native-go/backend/internal/helper/managed_pilot_test.go +210 -0
  323. package/templates/native-go/backend/internal/helper/nas_shipped_refusal_linux_test.go +97 -0
  324. package/templates/native-go/backend/internal/helper/native_discovery.go +79 -0
  325. package/templates/native-go/backend/internal/helper/native_identity.go +89 -0
  326. package/templates/native-go/backend/internal/helper/native_provider.go +159 -0
  327. package/templates/native-go/backend/internal/helper/native_provider_test.go +421 -0
  328. package/templates/native-go/backend/internal/helper/observation.go +204 -0
  329. package/templates/native-go/backend/internal/helper/observation_health_test.go +115 -0
  330. package/templates/native-go/backend/internal/helper/observation_reload_budget_test.go +117 -0
  331. package/templates/native-go/backend/internal/helper/observation_test.go +196 -0
  332. package/templates/native-go/backend/internal/helper/observer_diagnostic.go +109 -0
  333. package/templates/native-go/backend/internal/helper/observer_diagnostic_linux.go +76 -0
  334. package/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +124 -0
  335. package/templates/native-go/backend/internal/helper/observer_diagnostic_test.go +98 -0
  336. package/templates/native-go/backend/internal/helper/operation_bootstrap_linux.go +193 -0
  337. package/templates/native-go/backend/internal/helper/operation_credentials_linux.go +56 -0
  338. package/templates/native-go/backend/internal/helper/operation_linux.go +480 -0
  339. package/templates/native-go/backend/internal/helper/operation_linux_test.go +528 -0
  340. package/templates/native-go/backend/internal/helper/process_linux.go +11 -1
  341. package/templates/native-go/backend/internal/helper/publication_test.go +178 -0
  342. package/templates/native-go/backend/internal/helper/read_stream_cohort_linux_test.go +156 -0
  343. package/templates/native-go/backend/internal/helper/read_transfer.go +40 -0
  344. package/templates/native-go/backend/internal/helper/read_transfer_linux.go +109 -0
  345. package/templates/native-go/backend/internal/helper/read_transfer_linux_test.go +118 -0
  346. package/templates/native-go/backend/internal/helper/read_transfer_test.go +177 -0
  347. package/templates/native-go/backend/internal/helper/readonly.go +105 -0
  348. package/templates/native-go/backend/internal/helper/readonly_admission.go +85 -0
  349. package/templates/native-go/backend/internal/helper/readonly_cohort_linux_test.go +253 -0
  350. package/templates/native-go/backend/internal/helper/readonly_linux_test.go +378 -0
  351. package/templates/native-go/backend/internal/helper/readonly_mount_linux.go +65 -0
  352. package/templates/native-go/backend/internal/helper/readonly_mount_proxy_linux.go +113 -0
  353. package/templates/native-go/backend/internal/helper/readonly_operations_linux.go +168 -0
  354. package/templates/native-go/backend/internal/helper/readonly_resolver_linux.go +241 -0
  355. package/templates/native-go/backend/internal/helper/readonly_test.go +40 -0
  356. package/templates/native-go/backend/internal/helper/relaxed_identity.go +252 -0
  357. package/templates/native-go/backend/internal/helper/relaxed_identity_contract.go +105 -0
  358. package/templates/native-go/backend/internal/helper/relaxed_identity_test.go +406 -0
  359. package/templates/native-go/backend/internal/helper/relaxed_invalidation.go +200 -0
  360. package/templates/native-go/backend/internal/helper/repair.go +132 -0
  361. package/templates/native-go/backend/internal/helper/repair_test.go +271 -0
  362. package/templates/native-go/backend/internal/helper/s1r_actor_acl_linux_test.go +303 -0
  363. package/templates/native-go/backend/internal/helper/s1r_actor_fixture_linux_test.go +184 -0
  364. package/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +231 -0
  365. package/templates/native-go/backend/internal/helper/s1r_fixture_contract_linux_test.go +18 -0
  366. package/templates/native-go/backend/internal/helper/server_linux.go +44 -3
  367. package/templates/native-go/backend/internal/helper/status.go +74 -11
  368. package/templates/native-go/backend/internal/helper/status_test.go +83 -0
  369. package/templates/native-go/backend/internal/helper/supervision.go +28 -5
  370. package/templates/native-go/backend/internal/helper/supervisor_frame.go +76 -0
  371. package/templates/native-go/backend/internal/helper/supervisor_frame_linux_test.go +69 -0
  372. package/templates/native-go/backend/internal/helper/supervisor_frame_test.go +107 -0
  373. package/templates/native-go/backend/internal/helper/supervisor_linux.go +187 -16
  374. package/templates/native-go/backend/internal/helper/supervisor_linux_test.go +618 -7
  375. package/templates/native-go/backend/internal/helper/supervisor_socket_eof_test.go +74 -0
  376. package/templates/native-go/backend/internal/helper/supervisor_socket_test.go +45 -0
  377. package/templates/native-go/backend/internal/helper/testdata/protocol2/create.json +23 -0
  378. package/templates/native-go/backend/internal/helper/testdata/protocol2/frames.json +67 -0
  379. package/templates/native-go/backend/internal/helper/testdata/protocol2/grant-store.json +52 -0
  380. package/templates/native-go/backend/internal/helper/testdata/protocol2/intent.json +20 -0
  381. package/templates/native-go/backend/internal/helper/testdata/protocol2/list.json +20 -0
  382. package/templates/native-go/backend/internal/helper/testdata/protocol2/publish.json +20 -0
  383. package/templates/native-go/backend/internal/helper/testdata/protocol2/read.json +22 -0
  384. package/templates/native-go/backend/internal/helper/testdata/protocol2/stat.json +22 -0
  385. package/templates/native-go/backend/internal/helper/testdata/protocol2/write-stream.json +22 -0
  386. package/templates/native-go/backend/internal/helper/unit_connection.go +75 -0
  387. package/templates/native-go/backend/internal/helper/unit_connection_linux_test.go +135 -0
  388. package/templates/native-go/backend/internal/helper/unit_connection_test.go +133 -0
  389. package/templates/native-go/backend/internal/helper/unit_frame_test.go +32 -0
  390. package/templates/native-go/backend/internal/helper/unit_linux.go +364 -0
  391. package/templates/native-go/backend/internal/helper/unit_linux_test.go +46 -0
  392. package/templates/native-go/backend/internal/helper/unit_mechanisms_linux_test.go +217 -0
  393. package/templates/native-go/backend/internal/helper/unit_padding_linux_test.go +178 -0
  394. package/templates/native-go/backend/internal/helper/unit_query_linux.go +111 -0
  395. package/templates/native-go/backend/internal/helper/unit_reload_linux_test.go +372 -0
  396. package/templates/native-go/backend/internal/helper/unit_reload_sequence_linux_test.go +232 -0
  397. package/templates/native-go/backend/internal/helper/write.go +77 -0
  398. package/templates/native-go/backend/internal/helper/write_admission.go +260 -0
  399. package/templates/native-go/backend/internal/helper/write_admission_test.go +135 -0
  400. package/templates/native-go/backend/internal/helper/write_cohort_linux_test.go +218 -0
  401. package/templates/native-go/backend/internal/helper/write_files_linux.go +202 -0
  402. package/templates/native-go/backend/internal/helper/write_files_linux_test.go +199 -0
  403. package/templates/native-go/backend/internal/helper/write_intent_linux.go +116 -0
  404. package/templates/native-go/backend/internal/helper/write_intent_linux_test.go +74 -0
  405. package/templates/native-go/backend/internal/helper/write_operation_linux.go +245 -0
  406. package/templates/native-go/backend/internal/helper/write_test.go +53 -0
  407. package/templates/native-go/ui/app.js +8 -1
  408. package/templates/native-go-better-auth/node/build.mjs +2 -0
  409. package/templates/native-go-vue/README.md +115 -1
  410. package/templates/native-go-vue/frontend/DESIGN.md +1 -1
  411. package/templates/native-go-vue/frontend/package-lock.json +132 -229
  412. package/templates/native-go-vue/frontend/package.json +1 -1
  413. package/templates/native-go-vue/frontend/src/App.vue +33 -6
  414. package/templates/native-go-vue/frontend/src/context.ts +41 -2
  415. package/templates/native-go-vue/frontend/src/main.ts +4 -1
  416. package/templates/native-go-vue/frontend/src/nas/NasGrantSettings.vue +74 -0
  417. package/templates/native-go-vue/frontend/src/nas/NasPathPicker.vue +106 -0
  418. package/templates/native-go-vue/frontend/src/nas/NasUnavailable.vue +20 -0
  419. package/templates/native-go-vue/frontend/src/nas/i18n/de.json +74 -0
  420. package/templates/native-go-vue/frontend/src/nas/i18n/en.json +74 -0
  421. package/templates/native-go-vue/frontend/src/nas/i18n/es.json +74 -0
  422. package/templates/native-go-vue/frontend/src/nas/i18n/fr.json +74 -0
  423. package/templates/native-go-vue/frontend/src/nas/i18n/it.json +74 -0
  424. package/templates/native-go-vue/frontend/src/nas/i18n/ja.json +74 -0
  425. package/templates/native-go-vue/frontend/src/nas/i18n/ko.json +74 -0
  426. package/templates/native-go-vue/frontend/src/nas/i18n/zh-CN.json +74 -0
  427. package/templates/native-go-vue/frontend/src/nas/i18n/zh-TW.json +74 -0
  428. package/templates/native-go-vue/frontend/src/nas/i18n.ts +38 -0
  429. package/templates/native-go-vue/frontend/src/nas/mock-provider.ts +119 -0
  430. package/templates/native-go-vue/frontend/src/nas/provider.ts +59 -0
  431. package/templates/native-go-vue/frontend/src/nas/use-request.ts +27 -0
  432. package/templates/native-go-vue/frontend/src/style.css +17 -0
  433. package/templates/native-go-vue/frontend/test/apps.test.ts +44 -2
  434. package/templates/native-go-vue/frontend/test/nas-provider.test.ts +81 -0
  435. package/templates/native-go-vue/frontend/test/nas-request.test.ts +21 -0
  436. package/templates/native-go-vue/frontend/test/nas-ui.test.ts +261 -0
  437. package/templates/native-go-vue/frontend/tsconfig.json +1 -1
  438. package/templates/native-go-vue/frontend/vite.config.ts +6 -4
@@ -1,7 +1,15 @@
1
1
  <script setup lang="ts">
2
- import {computed, onMounted, onUnmounted, ref} from 'vue'
2
+ import {computed, inject, onMounted, onUnmounted, ref} from 'vue'
3
3
  import {AppRoot, Button, Callout, Dialog, SettingsSection, Textarea} from '@synopackageland/ui'
4
4
  import {stateCopy, type AppStatus, type Context, type Status} from './context'
5
+ import {NasProviderKey} from './nas/provider'
6
+ import {errorCopy, nasCopy} from './nas/i18n'
7
+ import NasGrantSettings from './nas/NasGrantSettings.vue'
8
+ import NasUnavailable from './nas/NasUnavailable.vue'
9
+ const nasProvider = inject(NasProviderKey, null)
10
+ // A mount owns one provider binding. A native subject/package switch must
11
+ // discard its UI and pending work; the host supplies a new provider on remount.
12
+ const nasInvalidated = ref(false)
5
13
  const props = defineProps<{ctx: Context}>()
6
14
  const app = ref<AppStatus>()
7
15
  const status = ref<Status>()
@@ -16,9 +24,16 @@ let disposed = false
16
24
  const refreshing = ref(false)
17
25
  let appCookie = ''
18
26
  const configured = computed(() => status.value?.reason !== "not-requested")
19
- const details = computed(() => status.value ? stateCopy[status.value.state] : undefined)
27
+ const details = computed(() => {
28
+ if(status.value?.state === 'pending') {
29
+ const copy = nasCopy(props.ctx.locale)
30
+ return {label:copy.healthPending,description:copy.healthPendingHelp}
31
+ }
32
+ return status.value ? stateCopy[status.value.state] : undefined
33
+ })
20
34
  function message(e: unknown) {
21
35
  const code = (e as {code?: string})?.code || 'request_failed'
36
+ if(['denied','unknown_method','unavailable','unsupported','session_required','auth_unavailable'].includes(code)) return errorCopy(e,nasCopy(props.ctx.locale))
22
37
  return ({session_required:'Your DSM session expired. Sign in again.',access_denied:'This sample belongs to another account.',integration_unavailable:'Integration is unavailable. Ask an administrator to activate or recover it.',personal_unavailable:'Sample storage is unavailable. Ask an administrator to check package data.',root_conflict:'A conflicting scheduler task exists. Ask an administrator to review it.',root_verify_failed:'Scheduler verification failed. Refresh and review the task.',root_run_failed:'The approved operation failed. Review integration status and cleanup.'} as Record<string,string>)[code] || `Request failed (${code}). Refresh and try again.`
23
38
  }
24
39
  async function refresh() {
@@ -27,6 +42,7 @@ async function refresh() {
27
42
  try {
28
43
  const [a,s] = await Promise.all([props.ctx.call<AppStatus>('app.status'),props.ctx.call<Status>('integration.status')])
29
44
  if(disposed) return
45
+ if(app.value && (app.value.user!==a.user || app.value.package!==a.package)) nasInvalidated.value=true
30
46
  app.value = a; status.value = s
31
47
  if(s.state !== 'ready') {id.value='';text.value='';return}
32
48
  // Plain --ui vue has no personal routes; not-enabled status hides this.
@@ -49,9 +65,16 @@ async function action(op: string) {
49
65
  if(approved !== 'ready') {notice.value='Approval cancelled. No operation was run.';return}
50
66
  await props.ctx.root.run(op)
51
67
  if(disposed) return
52
- notice.value='Operation completed. Integration status was checked again.'
68
+ notice.value=op==='helper_repair' ? 'Cleanup repaired. Use Recover or Approve and activate when ready.' : 'Operation completed. Integration status was checked again.'
69
+ await refresh()
70
+ } catch(e) {if(!disposed) {
53
71
  await refresh()
54
- } catch(e) {if(!disposed) {await refresh();if(!disposed) error.value=message(e)}}
72
+ if(!disposed) {
73
+ const code=(e as {code?:string})?.code
74
+ if(code==='root_cancelled') notice.value='Repair confirmation cancelled. No operation was run.'
75
+ else error.value=op==='helper_repair' && (code==='root_run_failed' || code==='root_task_failed') ? 'Repair could not verify safe cleanup. Review the package recovery instructions before trying again.' : message(e)
76
+ }
77
+ }}
55
78
  finally {if(!disposed) busy.value=false}
56
79
  }
57
80
  async function save() {
@@ -98,7 +121,7 @@ onUnmounted(()=>{disposed=true;appCookie='';text.value='';id.value=''})
98
121
  <SettingsSection title="DSM integration" :collapsible="false">
99
122
  <div v-if="status && details" :data-integration-state="status.state" class="integration-status" role="status">
100
123
  <h2>{{ details.label }}</h2><p>{{ details.description }}</p>
101
- <p v-if="status.cleanup === 'required'">Cleanup is required. Ask an administrator to run teardown or disable.</p>
124
+ <p v-if="status.cleanup === 'required'">Cleanup is required. Ask an administrator to run teardown or disable. If the helper supervisor was lost, use Repair cleanup and follow the package recovery instructions.</p>
102
125
  <dl><dt>Package running</dt><dd>{{ status.packageRunning }}</dd><dt>Scheduler</dt><dd>{{ status.scheduler }}</dd></dl>
103
126
  </div>
104
127
  <p v-else-if="error" role="status">Status could not be loaded. Refresh to try again.</p>
@@ -108,8 +131,10 @@ onUnmounted(()=>{disposed=true;appCookie='';text.value='';id.value=''})
108
131
  <Button variant="secondary" :disabled="busy || refreshing" @click="action('helper_recover')">Recover</Button>
109
132
  <Button variant="secondary" :disabled="busy || refreshing" @click="action('helper_teardown')">Teardown</Button>
110
133
  <Button variant="secondary" :disabled="busy || refreshing" @click="disableOpen=true">Disable</Button>
134
+ <Button variant="secondary" :disabled="busy || refreshing" @click="action('helper_repair')">Repair cleanup</Button>
111
135
  </div>
112
- <Callout v-if="app && !app.admin && status?.state !== 'ready'" title="Administrator action needed">Ask a DSM administrator to open this package's settings. Your login cannot approve root operations.</Callout>
136
+ <p v-if="app?.admin && ctx.root && configured" class="integration-help">Repair cleanup clears verified leftover helper state. It does not restart integration.</p>
137
+ <Callout v-if="app && !app.admin && status?.state !== 'ready' && status?.state !== 'pending'" title="Administrator action needed">Ask a DSM administrator to open this package's settings. Your login cannot approve root operations.</Callout>
113
138
  </SettingsSection>
114
139
  <SettingsSection v-if="status?.state === 'ready'" title="My sample data" :collapsible="false">
115
140
  <p class="integration-help">This synthetic note belongs to your DSM account and is stored in package data.</p>
@@ -118,6 +143,8 @@ onUnmounted(()=>{disposed=true;appCookie='';text.value='';id.value=''})
118
143
  <label v-if="id" class="integration-field"><span>My sample note</span><Textarea v-model="text" aria-label="My sample note" :disabled="busy || refreshing" /></label>
119
144
  <Button v-if="id" variant="primary" :disabled="busy || refreshing" @click="save">Save my note</Button>
120
145
  </SettingsSection>
146
+ <NasGrantSettings v-if="nasProvider && app && status && !nasInvalidated" :locale="ctx.locale" />
147
+ <NasUnavailable v-else :locale="ctx.locale" />
121
148
  <SettingsSection v-if="hasIdentity" title="Optional app identity" :collapsible="false">
122
149
  <p class="integration-help">Your DSM login is checked again for every app session request.</p>
123
150
  <div class="integration-actions"><Button variant="primary" :disabled="busy || refreshing" @click="login">Create app session</Button><Button variant="secondary" :disabled="busy || refreshing || !identity" @click="checkIdentity">Check app session</Button></div>
@@ -1,14 +1,53 @@
1
- export type IntegrationState = 'not-enabled' | 'ready' | 'needs-approval' | 'incompatible' | 'stopped' | 'failed'
1
+ export type IntegrationState = 'not-enabled' | 'ready' | 'needs-approval' | 'incompatible' | 'stopped' | 'failed' | 'pending'
2
2
  export interface Status {state: IntegrationState; reason?: string; cleanup?: string; packageRunning: string; scheduler: string}
3
+ export interface HostPlatformSnapshot {
4
+ readonly web: boolean
5
+ readonly host: 'dsm' | 'standalone-web' | 'unavailable'
6
+ readonly dsmStandalone: boolean | null
7
+ readonly dsmLanguage: string | null
8
+ readonly appLocale: string | null
9
+ readonly systemVersion: string | null
10
+ readonly fullVersion: string | null
11
+ readonly theme: null
12
+ }
13
+ export type HostTitleResult = {status: 'ok'; target: 'dsm-window' | 'document'} |
14
+ {status: 'unsupported' | 'unavailable' | 'invalid-input' | 'failed'}
15
+ export type HostRequestResult = {status: 'requested'} |
16
+ {status: 'unsupported' | 'unavailable' | 'invalid-input' | 'blocked' | 'failed'}
17
+ export type HostURLResult = {status: 'requested'; windowHandleAvailable: boolean} |
18
+ {status: 'unsupported' | 'unavailable' | 'invalid-input' | 'failed'}
19
+ export type HostEvent = 'window-resize' | 'host-theme-change' | 'host-language-change'
20
+ export type HostSubscriptionResult = {status: 'subscribed'; dispose(): void} |
21
+ {status: 'unsupported' | 'unavailable' | 'invalid-input' | 'failed'}
22
+ export type HostFileNavigationResult = {status: 'requested'; action: 'locate-folder' | 'highlight-file'} |
23
+ {status: 'unsupported' | 'unavailable' | 'invalid-input' | 'failed'}
24
+ export type HostUnsupportedResult = {status: 'unsupported' | 'unavailable'}
25
+ export interface HostAdapter {
26
+ platform(): HostPlatformSnapshot
27
+ setTitle(title: string): HostTitleResult
28
+ activateWindow(): HostRequestResult
29
+ requestClose(): HostRequestResult
30
+ openApp(appId: string): HostRequestResult
31
+ openURL(url: string): HostURLResult
32
+ openFileManager(path: string): HostFileNavigationResult
33
+ revealFile(path: string): HostFileNavigationResult
34
+ openFile(path: string): HostUnsupportedResult
35
+ showFileDetails(paths: readonly string[]): HostUnsupportedResult
36
+ openAppSetting(): HostUnsupportedResult
37
+ subscribe(event: HostEvent, listener: () => void): HostSubscriptionResult
38
+ dispose(): void
39
+ }
3
40
  export interface Context {
4
41
  call<T = unknown>(method: string, params?: Record<string, unknown>): Promise<T>
5
- reopen(fn: () => void): void
42
+ reopen(fn: () => void): () => void
6
43
  locale: string
44
+ host: HostAdapter
7
45
  root?: {state(op: string): Promise<string>; authorize(op: string): Promise<string>; run(op: string): Promise<unknown>; remove(op: string): Promise<string>}
8
46
  }
9
47
  export interface AppStatus {package: string; version: string; user: string; admin: boolean}
10
48
  export const stateCopy: Record<IntegrationState, {label: string; description: string}> = {
11
49
  'not-enabled': {label: 'Not enabled', description: 'An administrator can enable integration for this package.'},
50
+ pending: {label: 'Temporarily revalidating', description: 'Integration is temporarily revalidating. Wait, then refresh. New access is unavailable until verification completes.'},
12
51
  ready: {label: 'Ready', description: 'The helper passed a fresh trusted health check.'},
13
52
  'needs-approval': {label: 'Approval required', description: 'Ask an administrator to approve and activate integration.'},
14
53
  incompatible: {label: 'Incompatible', description: 'Inventory or trust checks failed. Ask an administrator to review this package.'},
@@ -1,12 +1,15 @@
1
1
  import {createApp} from 'vue'
2
2
  import App from './App.vue'
3
3
  import type {Context} from './context'
4
+ import {NasProviderKey, type NasProvider} from './nas/provider'
4
5
  import '@synopackageland/ui/themes/dsm7-embedded.css'
5
6
  import './style.css'
6
7
 
7
8
  let mountSequence = 0
8
- export function mount(root: HTMLElement, ctx: Context) {
9
+ export function mount(root: HTMLElement, ctx: Context, options: {nasProvider?: NasProvider} = {}) {
9
10
  const app = createApp(App, {ctx})
11
+ // The shipped strict-S1 build never installs a NAS provider. Preview is dev/mock only.
12
+ if(import.meta.env.DEV && options.nasProvider?.mode === 'mock') app.provide(NasProviderKey, options.nasProvider)
10
13
  // Include the generated package ID, an instance counter and randomness even
11
14
  // across separately loaded bundles. getRandomValues also works on DSM HTTP.
12
15
  app.config.idPrefix = `__PACKAGE__-${++mountSequence}-${crypto.getRandomValues(new Uint32Array(4)).join('-')}`
@@ -0,0 +1,74 @@
1
+ <script setup lang="ts">
2
+ import {computed, inject, onMounted, ref} from 'vue'
3
+ import {Button, Callout, Dialog, SettingsSection} from '@synopackageland/ui'
4
+ import {NasProviderKey, type GrantView, type ScopeKind} from './provider'
5
+ import {actionCopy, errorCopy, nasCopy} from './i18n'
6
+ import {useNasRequest} from './use-request'
7
+ import NasPathPicker from './NasPathPicker.vue'
8
+
9
+ const props=defineProps<{locale:string}>()
10
+ const provider=inject(NasProviderKey)!
11
+ const copy=computed(()=>nasCopy(props.locale))
12
+ const request=useNasRequest(), {busy,error}=request
13
+ const items=ref<GrantView[]>([]), canManageShared=ref(false), pickerOpen=ref(false), kind=ref<ScopeKind>('user-personal'), revokeTarget=ref<GrantView>(), notice=ref('')
14
+ const revokeOpen=computed({get:()=>!!revokeTarget.value,set:value=>{if(!value){request.cancel();revokeTarget.value=undefined}}})
15
+ async function refresh() {
16
+ const result=await request.run(signal=>provider.settings(signal))
17
+ if(result) {items.value=result.items;canManageShared.value=result.canManageShared}
18
+ }
19
+ function choose(scope:ScopeKind) {kind.value=scope;notice.value='';pickerOpen.value=true}
20
+ async function granted() {notice.value=copy.value.noticeCreated;await refresh()}
21
+ function state(item:GrantView) {
22
+ if(item.effectiveState==='active') return copy.value.active
23
+ if(item.effectiveState==='suspended') return copy.value.suspended
24
+ if(item.cleanupRequired) return copy.value.cleanup
25
+ return item.drained===true?copy.value.revoked:copy.value.draining
26
+ }
27
+ function created(time:number) {
28
+ try {return new Intl.DateTimeFormat(props.locale.replace('_','-'),{dateStyle:'medium',timeStyle:'short'}).format(time)}
29
+ catch {return new Intl.DateTimeFormat('en',{dateStyle:'medium',timeStyle:'short'}).format(time)}
30
+ }
31
+ async function revoke() {
32
+ const target=revokeTarget.value;if(!target) return
33
+ const result=await request.run(signal=>provider.revoke(target.grantId,target.revision,signal))
34
+ if(result) {
35
+ // Only an R receipt sets revoked; only Q sets drained. Timeout is neither.
36
+ if(result.revoked) {const item=items.value.find(i=>i.grantId===result.grantId);if(item){item.effectiveState='revoked';item.revision=result.grantRevision;item.drained=result.drained}}
37
+ revokeTarget.value=undefined
38
+ }
39
+ }
40
+ onMounted(refresh)
41
+ </script>
42
+
43
+ <template>
44
+ <SettingsSection :title="copy.title" :collapsible="false" class="nas-settings" :aria-busy="busy">
45
+ <Callout tone="info" :title="copy.pilotOff">{{ copy.pilotRestrictions }}</Callout>
46
+ <p v-if="provider.mode === 'mock'" class="integration-help">{{ copy.mock }}</p>
47
+ <Callout v-if="error" tone="danger" :title="copy.errorTitle" role="alert">{{ errorCopy(error,copy) }}</Callout>
48
+ <div class="integration-actions">
49
+ <Button variant="primary" :disabled="busy || pickerOpen" @click="choose('user-personal')">{{ copy.choosePersonal }}</Button>
50
+ <Button v-if="canManageShared" variant="secondary" :disabled="busy || pickerOpen" @click="choose('app-shared')">{{ copy.chooseShared }}</Button>
51
+ <Button variant="secondary" :disabled="busy || pickerOpen" @click="refresh">{{ copy.refresh }}</Button>
52
+ </div>
53
+ <p v-if="notice" role="status">{{ notice }}</p>
54
+ <p v-if="busy" role="status">{{ copy.loading }}</p>
55
+ <p v-else-if="!items.length">{{ copy.emptyGrant }}</p>
56
+ <ul v-else class="nas-grants">
57
+ <li v-for="item in items" :key="item.grantId">
58
+ <div class="nas-grant-heading"><strong>{{ item.displayName }}</strong><Button v-if="item.canRevoke && item.effectiveState !== 'revoked'" variant="secondary" :disabled="busy || pickerOpen" @click="revokeTarget=item">{{ copy.revoke }}</Button></div>
59
+ <dl class="nas-summary">
60
+ <dt>{{ copy.scope }}</dt><dd>{{ item.scopeKind === 'user-personal' ? copy.personal : copy.shared }}</dd>
61
+ <dt>{{ copy.actions }}</dt><dd>{{ actionCopy(item.actions,copy) }}</dd>
62
+ <dt>{{ copy.state }}</dt><dd role="status">{{ state(item) }}</dd>
63
+ <dt>{{ copy.createdAt }}</dt><dd>{{ created(item.createdAt) }}</dd>
64
+ </dl>
65
+ </li>
66
+ </ul>
67
+ <NasPathPicker v-model:open="pickerOpen" :scope-kind="kind" :locale="locale" @granted="granted" />
68
+ <Dialog v-model:open="revokeOpen" :title="copy.revokeTitle" :description="copy.revokeWarning" :close-label="copy.close">
69
+ <p>{{ revokeTarget?.displayName }}</p>
70
+ <Callout v-if="error" tone="danger" :title="copy.errorTitle" role="alert">{{ errorCopy(error,copy) }}</Callout>
71
+ <template #footer><Button variant="secondary" @click="revokeOpen=false">{{ copy.cancel }}</Button><Button variant="danger" :disabled="busy" @click="revoke">{{ copy.confirmRevoke }}</Button></template>
72
+ </Dialog>
73
+ </SettingsSection>
74
+ </template>
@@ -0,0 +1,106 @@
1
+ <script setup lang="ts">
2
+ import {computed, inject, onBeforeUnmount, ref, watch} from 'vue'
3
+ import {Button, Callout, DataGrid, Dialog, TreeView, type TreeNode} from '@synopackageland/ui'
4
+ import {NasProviderKey, type FolderEntry, type PickerContext, type PreparedIntent, type GrantHandle, type ScopeKind} from './provider'
5
+ import {actionCopy, errorCopy, format, nasCopy} from './i18n'
6
+ import {useNasRequest} from './use-request'
7
+
8
+ const props=defineProps<{open:boolean; scopeKind:ScopeKind; locale:string}>()
9
+ const emit=defineEmits<{'update:open':[value:boolean]; granted:[grant:GrantHandle]}>()
10
+ const provider=inject(NasProviderKey)!
11
+ const copy=computed(()=>nasCopy(props.locale))
12
+ const request=useNasRequest(), {busy,error}=request
13
+ const context=ref<PickerContext>(), entries=ref<FolderEntry[]>([]), roots=ref<TreeNode[]>([])
14
+ const path=ref<Array<{id:string;name:string}>>([]), selected=ref<FolderEntry>(), intent=ref<PreparedIntent>(), nextCursor=ref<string>()
15
+ const columns=computed(()=>[{key:'displayName',label:copy.value.folder,width:'65%'},{key:'selection',label:copy.value.selection,width:'35%'}])
16
+ const rows=computed(()=>entries.value.map(e=>({...e})))
17
+
18
+ function discard() {
19
+ request.cancel()
20
+ const id=context.value?.contextId;context.value=undefined
21
+ entries.value=[];roots.value=[];path.value=[];selected.value=undefined;intent.value=undefined;nextCursor.value=undefined
22
+ if(id) void provider.cancel(id).catch(()=>{})
23
+ }
24
+ function close() {discard();emit('update:open',false)}
25
+ async function start() {
26
+ discard()
27
+ const result=await request.run(async(signal,current)=> {
28
+ const ctx=await provider.begin(props.scopeKind,signal)
29
+ // A provider which ignores abort must still have its late context canceled.
30
+ if(!current() || signal.aborted) {await provider.cancel(ctx.contextId);throw {code:'canceled'}}
31
+ context.value=ctx
32
+ return provider.list(ctx.contextId,undefined,undefined,signal)
33
+ })
34
+ if(result) {entries.value=result.entries;roots.value=result.entries.map(e=>({id:e.nodeId,label:e.displayName}));nextCursor.value=result.nextCursor}
35
+ }
36
+ async function browse(target:Array<{id:string;name:string}>, more=false) {
37
+ if(!context.value) return
38
+ const ctx=context.value, node=target.at(-1)?.id
39
+ const result=await request.run(signal=>provider.list(ctx.contextId,node,more?nextCursor.value:undefined,signal))
40
+ if(result) {
41
+ path.value=target;entries.value=more?[...entries.value,...result.entries]:result.entries
42
+ // Bound the rendered list too; pages do not grow an unbounded DOM.
43
+ if(entries.value.length>200) entries.value=entries.value.slice(-200)
44
+ if(target.length===0) roots.value=entries.value.map(e=>({id:e.nodeId,label:e.displayName}))
45
+ nextCursor.value=result.nextCursor;selected.value=undefined;intent.value=undefined
46
+ }
47
+ }
48
+ function openFolder(id:string,name:string) {void browse([...path.value,{id,name}])}
49
+ async function review() {
50
+ if(!selected.value) return
51
+ const result=await request.run(signal=>provider.prepare(selected.value!.nodeId,signal))
52
+ if(result) intent.value=result
53
+ }
54
+ async function confirm() {
55
+ if(!intent.value) return
56
+ const prepared=intent.value
57
+ const result=await request.run(signal=>provider.confirm(prepared.intentId,prepared.summaryDigest,signal))
58
+ if(result) {emit('granted',result);close()}
59
+ }
60
+ watch(()=>props.open,open=>{if(open) void start();else discard()},{immediate:true})
61
+ watch(()=>props.scopeKind,()=>{if(props.open) void start()})
62
+ onBeforeUnmount(discard)
63
+ </script>
64
+
65
+ <template>
66
+ <Dialog :open="open" :title="intent ? copy.summaryTitle : copy.pickerTitle" :description="copy.pickerHelp" :close-label="copy.close" width="720px" @update:open="value => {if(!value) close()}">
67
+ <div class="nas-picker" :aria-busy="busy">
68
+ <p v-if="provider.mode === 'mock'" class="integration-help">{{ copy.mock }}</p>
69
+ <Callout v-if="error" tone="danger" :title="copy.errorTitle" role="alert">{{ errorCopy(error,copy) }}</Callout>
70
+ <p v-if="busy" role="status">{{ copy.loading }}</p>
71
+ <template v-if="intent">
72
+ <dl class="nas-summary">
73
+ <dt>{{ copy.app }}</dt><dd>{{ intent.summary.appName }}</dd>
74
+ <dt>{{ copy.scope }}</dt><dd>{{ intent.summary.scopeKind === 'user-personal' ? copy.personal : copy.shared }}</dd>
75
+ <dt>{{ copy.folder }}</dt><dd>{{ intent.summary.displayName }}</dd>
76
+ <dt>{{ copy.actions }}</dt><dd>{{ actionCopy(intent.summary.actions,copy) }}</dd>
77
+ </dl>
78
+ <p>{{ copy.persistent }}</p><p>{{ copy.revokeHow }}</p><p>{{ copy.expires }}</p>
79
+ </template>
80
+ <template v-else-if="context">
81
+ <nav class="nas-breadcrumb" :aria-label="copy.folder">
82
+ <Button v-if="path.length" variant="secondary" :disabled="busy" @click="browse(path.slice(0,-1))">{{ copy.back }}</Button>
83
+ <Button variant="secondary" :disabled="busy" @click="browse([])">{{ copy.roots }}</Button>
84
+ <Button v-for="(part,index) in path" :key="part.id" variant="secondary" :disabled="busy" @click="browse(path.slice(0,index+1))">{{ part.name }}</Button>
85
+ </nav>
86
+ <div class="nas-browser">
87
+ <aside class="nas-tree" :aria-label="copy.roots" :inert="busy || undefined"><TreeView :nodes="roots" :show-icons="false" @select="node => browse([{id:node.id,name:node.label}])" /></aside>
88
+ <div class="nas-folder-list">
89
+ <DataGrid :columns="columns" :rows="rows" row-key="nodeId" :footer="false" :labels="{empty:copy.emptyFolder}" :resizable="false" :loading="busy" :loading-text="copy.loading">
90
+ <template #cell-displayName="{row}"><Button variant="secondary" class="nas-folder-name" :disabled="busy" @click="openFolder(String(row.nodeId),String(row.displayName))">{{ format(copy.open,String(row.displayName)) }}</Button></template>
91
+ <template #cell-selection="{row}"><Button variant="secondary" class="nas-folder-action" :disabled="busy || !row.selectable" :aria-label="format(copy.select,String(row.displayName))" :aria-pressed="selected?.nodeId === row.nodeId" @click="selected=entries.find(e=>e.nodeId===row.nodeId)">{{ copy.selection }}</Button></template>
92
+ </DataGrid>
93
+ <Button v-if="nextCursor" variant="secondary" :disabled="busy" @click="browse(path,true)">{{ copy.loadMore }}</Button>
94
+ </div>
95
+ </div>
96
+ <p v-if="selected" role="status">{{ format(copy.selected,selected.displayName) }}</p>
97
+ </template>
98
+ </div>
99
+ <template #footer>
100
+ <Button variant="secondary" @click="close">{{ copy.cancel }}</Button>
101
+ <Button v-if="!context && !busy" variant="secondary" @click="start">{{ copy.retry }}</Button>
102
+ <Button v-if="intent" variant="primary" :disabled="busy" @click="confirm">{{ copy.confirm }}</Button>
103
+ <Button v-else variant="primary" :disabled="busy || !selected" @click="review">{{ copy.review }}</Button>
104
+ </template>
105
+ </Dialog>
106
+ </template>
@@ -0,0 +1,20 @@
1
+ <script setup lang="ts">
2
+ import {computed} from 'vue'
3
+ import {Callout, SettingsSection} from '@synopackageland/ui'
4
+ import {nasCopy} from './i18n'
5
+ const props=defineProps<{locale:string}>()
6
+ const copy=computed(()=>nasCopy(props.locale))
7
+ </script>
8
+
9
+ <template>
10
+ <SettingsSection :title="copy.title" :collapsible="false" data-nas-state="unavailable">
11
+ <Callout :title="copy.unavailableTitle">
12
+ <p>{{ copy.unavailableMessage }}</p>
13
+ <p>{{ copy.pilotUnavailable }}</p>
14
+ <p>{{ copy.noUnlock }}</p>
15
+ <p>{{ copy.relaxedRisk }}</p>
16
+ <p>{{ copy.relaxedReauthorize }}</p>
17
+ <p>{{ copy.relaxedPermissions }}</p>
18
+ </Callout>
19
+ </SettingsSection>
20
+ </template>
@@ -0,0 +1,74 @@
1
+ {
2
+ "title": "NAS-Ordnerzugriff",
3
+ "mock": "Mock-Vorschau — NAS-Dateien und Berechtigungen bleiben unverändert.",
4
+ "personal": "Meine Ordner",
5
+ "shared": "Gemeinsame App-Ordner",
6
+ "choosePersonal": "Eigenen Ordner wählen",
7
+ "chooseShared": "Gemeinsamen Ordner wählen",
8
+ "refresh": "Zugriff aktualisieren",
9
+ "emptyGrant": "Keine Ordner freigegeben. Wählen Sie einen Ordner für die Vorschau des Lesezugriffs.",
10
+ "pickerTitle": "NAS-Ordner wählen",
11
+ "pickerHelp": "Ordner durchsuchen, auswählen und den Lesezugriff prüfen.",
12
+ "roots": "Ordner",
13
+ "back": "Zurück",
14
+ "open": "{name} öffnen",
15
+ "select": "{name} auswählen",
16
+ "selected": "Ausgewählt: {name}",
17
+ "review": "Zugriff prüfen",
18
+ "cancel": "Abbrechen",
19
+ "confirm": "Zugriff bestätigen",
20
+ "summaryTitle": "Ordnerzugriff prüfen",
21
+ "app": "App",
22
+ "scope": "Bereich",
23
+ "folder": "Ordner",
24
+ "actions": "Erlaubte Aktionen",
25
+ "readOnly": "Ordner auflisten, Metadaten prüfen und Dateien lesen",
26
+ "persistent": "Dauerhafter Zugriff bis zum Widerruf oder bis die Bindung ungültig wird.",
27
+ "revokeHow": "Widerrufen Sie einzelne Ordner hier. Eine neue Freigabe erzeugt einen neuen Grant.",
28
+ "expires": "Innerhalb von 30 Sekunden bestätigen.",
29
+ "loading": "Ordner werden geladen…",
30
+ "emptyFolder": "Dieser Ordner ist leer",
31
+ "loadMore": "Mehr laden",
32
+ "state": "Zugriffsstatus",
33
+ "active": "Aktiv",
34
+ "suspended": "Ausgesetzt — erneut auswählen und freigeben",
35
+ "revoked": "Widerrufen",
36
+ "draining": "Widerrufen; Übertragungen werden gestoppt",
37
+ "cleanup": "Widerrufen; Bereinigung muss geprüft werden",
38
+ "createdAt": "Erstellt",
39
+ "revoke": "Widerrufen",
40
+ "revokeTitle": "Ordnerzugriff widerrufen?",
41
+ "revokeWarning": "Neuen Zugriff und laufende Übertragungen stoppen. Bereits gesendete oder geschriebene Daten werden nicht zurückgesetzt.",
42
+ "confirmRevoke": "Widerruf bestätigen",
43
+ "noticeCreated": "Ordnerzugriff hinzugefügt.",
44
+ "errorTitle": "Ordnerzugriff konnte nicht aktualisiert werden",
45
+ "errorDenied": "Zugriff verweigert. Wählen Sie einen für Ihr aktuelles Konto sichtbaren Ordner.",
46
+ "errorExpired": "Auswahl oder Bestätigung abgelaufen. Abbrechen und den Ordner erneut wählen.",
47
+ "errorStale": "Sitzung oder Auswahl geändert. Abbrechen und den Ordner erneut wählen.",
48
+ "errorUnavailable": "Ordnerdienst nicht verfügbar. Bitten Sie einen Administrator, Integration und Home-Dienste zu prüfen.",
49
+ "errorBusy": "Anfragelimit erreicht. Warten Sie und versuchen Sie es erneut.",
50
+ "errorCanceled": "Anfrage abgebrochen. Wählen Sie den Ordner erneut, wenn Sie bereit sind.",
51
+ "errorInternal": "Anfrage fehlgeschlagen. Aktualisieren Sie den Zugriff vor einem neuen Versuch.",
52
+ "retry": "Erneut versuchen",
53
+ "close": "Schließen",
54
+ "selection": "Ordner auswählen",
55
+ "actionList": "Ordner auflisten",
56
+ "actionStat": "Metadaten prüfen",
57
+ "actionRead": "Dateien lesen",
58
+ "pilotOff": "Pilot für verwaltete Konten: aus",
59
+ "pilotRestrictions": "Die Freigabe durch einen Administrator und ein geprüfter Ablauf zur Kontenpflege sind erforderlich. Kontoänderungen oder eine ungeprüfte Identität entziehen den Zugriff und erfordern eine neue Anmeldung und Freigabe. Diese Version kann den Pilotbetrieb nicht aktivieren.",
60
+ "unavailableTitle": "Noch nicht verfügbar",
61
+ "unavailableMessage": "NAS-Ordnerfreigaben und Dateioperationen sind noch nicht verfügbar. Die erforderlichen nativen Identitäts- und Berechtigungsnachweise können derzeit nicht geprüft werden.",
62
+ "pilotUnavailable": "Der Pilot B für verwaltete Konten ist experimental und kann nicht aktiviert werden.",
63
+ "noUnlock": "Das Aktivieren der Integration oder erneutes Anmelden schaltet den NAS-Dateizugriff nicht frei.",
64
+ "errorUnknownMethod": "Diese Paketversion stellt diese Methode nicht bereit.",
65
+ "errorNativeProof": "Der erforderliche native Identitäts- oder Berechtigungsnachweis fehlt. Der NAS-Zugriff bleibt gesperrt.",
66
+ "errorSession": "Ihre DSM-Sitzung ist abgelaufen. Melden Sie sich erneut für die App-Sitzung an; der NAS-Dateizugriff bleibt nicht verfügbar.",
67
+ "errorAuthentication": "Die DSM-Authentifizierung ist nicht verfügbar. Aktualisieren Sie den App-Status später.",
68
+ "errorUnsupported": "NAS-Dateioperationen sind in diesem Build nicht verfügbar.",
69
+ "healthPending": "Vorübergehende erneute Prüfung",
70
+ "healthPendingHelp": "Die Integration wird vorübergehend erneut geprüft. Warten Sie und aktualisieren Sie anschließend. Neuer Zugriff ist erst nach Abschluss der Prüfung möglich.",
71
+ "relaxedRisk": "Bei gelockerter Identität können mit derselben UID und demselben username neu erstellte Konten bestehende Freigaben übernehmen.",
72
+ "relaxedReauthorize": "Ändert sich die UID oder der username, werden alle Ihre Freigaben ungültig und müssen erneut genehmigt werden.",
73
+ "relaxedPermissions": "Dateioperationen verwenden Ihre UID und Gruppen und bleiben auf NAS-Berechtigungen und genehmigte Ordner beschränkt. Deaktivierte Konten oder entzogene App-Berechtigungen führen zur Zugriffsverweigerung."
74
+ }
@@ -0,0 +1,74 @@
1
+ {
2
+ "title": "NAS folder access",
3
+ "mock": "Mock preview — no NAS files or permissions are changed.",
4
+ "personal": "My folders",
5
+ "shared": "App shared folders",
6
+ "choosePersonal": "Choose my folder",
7
+ "chooseShared": "Choose shared folder",
8
+ "refresh": "Refresh access",
9
+ "emptyGrant": "No folders authorized. Choose a folder to preview read-only access.",
10
+ "pickerTitle": "Choose a NAS folder",
11
+ "pickerHelp": "Browse folders, select one, then review read-only access.",
12
+ "roots": "Folders",
13
+ "back": "Back",
14
+ "open": "Open {name}",
15
+ "select": "Select {name}",
16
+ "selected": "Selected: {name}",
17
+ "review": "Review access",
18
+ "cancel": "Cancel",
19
+ "confirm": "Confirm access",
20
+ "summaryTitle": "Review folder access",
21
+ "app": "App",
22
+ "scope": "Scope",
23
+ "folder": "Folder",
24
+ "actions": "Allowed actions",
25
+ "readOnly": "List folders, inspect metadata and read files",
26
+ "persistent": "Persistent access — until you revoke it or its binding becomes invalid.",
27
+ "revokeHow": "Revoke individual folders here. Reauthorization creates a new grant.",
28
+ "expires": "Confirm within 30 seconds.",
29
+ "loading": "Loading folders…",
30
+ "emptyFolder": "This folder is empty",
31
+ "loadMore": "Load more",
32
+ "state": "Access state",
33
+ "active": "Active",
34
+ "suspended": "Suspended — select again to authorize",
35
+ "revoked": "Revoked",
36
+ "draining": "Revoked; stopping transfers",
37
+ "cleanup": "Revoked; cleanup needs verification",
38
+ "createdAt": "Created",
39
+ "revoke": "Revoke",
40
+ "revokeTitle": "Revoke folder access?",
41
+ "revokeWarning": "Stop new access and in-progress transfers. Data already sent or written will not be restored.",
42
+ "confirmRevoke": "Confirm revoke",
43
+ "noticeCreated": "Folder access added.",
44
+ "errorTitle": "Folder access could not be updated",
45
+ "errorDenied": "Access denied. Choose a folder visible to your current account.",
46
+ "errorExpired": "The selection or confirmation expired. Cancel and choose the folder again.",
47
+ "errorStale": "Your session or selection changed. Cancel and choose the folder again.",
48
+ "errorUnavailable": "Folder service is unavailable. Ask an administrator to check integration and home services.",
49
+ "errorBusy": "The request limit was reached. Wait, then retry.",
50
+ "errorCanceled": "The request was canceled. Choose the folder again when ready.",
51
+ "errorInternal": "The request failed. Refresh access before trying again.",
52
+ "retry": "Retry",
53
+ "close": "Close",
54
+ "selection": "Select folder",
55
+ "actionList": "List folders",
56
+ "actionStat": "Inspect metadata",
57
+ "actionRead": "Read files",
58
+ "pilotOff": "Managed account pilot: off",
59
+ "pilotRestrictions": "Administrator approval and a verified account-maintenance process are required. Account changes or unverified identity revoke access and require a new sign-in and approval. Enabling this pilot is unavailable in this build.",
60
+ "unavailableTitle": "Not available yet",
61
+ "unavailableMessage": "NAS folder grants and file operations are not available yet. Required native identity and permission proof cannot currently be verified.",
62
+ "pilotUnavailable": "Managed account pilot B is experimental and cannot be enabled.",
63
+ "noUnlock": "Enabling integration or signing in again does not unlock NAS file access.",
64
+ "errorUnknownMethod": "This method is not provided by this package version.",
65
+ "errorNativeProof": "Required native identity or permission proof is unavailable. NAS access remains closed.",
66
+ "errorSession": "Your DSM session expired. Sign in to restore the app session; NAS file access remains unavailable.",
67
+ "errorAuthentication": "DSM authentication is unavailable. Refresh the app status later.",
68
+ "errorUnsupported": "NAS file operations are not available in this build.",
69
+ "healthPending": "Temporarily revalidating",
70
+ "healthPendingHelp": "Integration is temporarily revalidating. Wait, then refresh. New access is unavailable until verification completes.",
71
+ "relaxedRisk": "When relaxed identity is selected, accounts recreated with the same UID and username may retain grants.",
72
+ "relaxedReauthorize": "A UID or username change invalidates all your grants and requires new authorization.",
73
+ "relaxedPermissions": "File operations use your UID and groups, within NAS permissions and authorized folders. Disabled accounts or revoked app access are denied."
74
+ }
@@ -0,0 +1,74 @@
1
+ {
2
+ "title": "Acceso a carpetas NAS",
3
+ "mock": "Vista previa simulada — no se cambian archivos ni permisos del NAS.",
4
+ "personal": "Mis carpetas",
5
+ "shared": "Carpetas compartidas de la App",
6
+ "choosePersonal": "Elegir mi carpeta",
7
+ "chooseShared": "Elegir carpeta compartida",
8
+ "refresh": "Actualizar accesos",
9
+ "emptyGrant": "No hay carpetas autorizadas. Elija una carpeta para ver el acceso de solo lectura.",
10
+ "pickerTitle": "Elegir una carpeta NAS",
11
+ "pickerHelp": "Explore las carpetas, seleccione una y revise el acceso de solo lectura.",
12
+ "roots": "Carpetas",
13
+ "back": "Volver",
14
+ "open": "Abrir {name}",
15
+ "select": "Seleccionar {name}",
16
+ "selected": "Selección: {name}",
17
+ "review": "Revisar acceso",
18
+ "cancel": "Cancelar",
19
+ "confirm": "Confirmar acceso",
20
+ "summaryTitle": "Revisar acceso a la carpeta",
21
+ "app": "App",
22
+ "scope": "Ámbito",
23
+ "folder": "Carpeta",
24
+ "actions": "Acciones permitidas",
25
+ "readOnly": "Listar carpetas, consultar metadatos y leer archivos",
26
+ "persistent": "Acceso persistente hasta que lo revoque o su vínculo deje de ser válido.",
27
+ "revokeHow": "Revoque cada carpeta aquí. Una nueva autorización crea un nuevo grant.",
28
+ "expires": "Confirme en 30 segundos.",
29
+ "loading": "Cargando carpetas…",
30
+ "emptyFolder": "Esta carpeta está vacía",
31
+ "loadMore": "Cargar más",
32
+ "state": "Estado del acceso",
33
+ "active": "Activo",
34
+ "suspended": "Suspendido — seleccione de nuevo para autorizar",
35
+ "revoked": "Revocado",
36
+ "draining": "Revocado; deteniendo transferencias",
37
+ "cleanup": "Revocado; limpieza pendiente de verificación",
38
+ "createdAt": "Creado",
39
+ "revoke": "Revocar",
40
+ "revokeTitle": "¿Revocar acceso a la carpeta?",
41
+ "revokeWarning": "Detener nuevos accesos y transferencias en curso. Los datos ya enviados o escritos no se restaurarán.",
42
+ "confirmRevoke": "Confirmar revocación",
43
+ "noticeCreated": "Acceso a la carpeta añadido.",
44
+ "errorTitle": "No se pudo actualizar el acceso a la carpeta",
45
+ "errorDenied": "Acceso denegado. Elija una carpeta visible para su cuenta actual.",
46
+ "errorExpired": "La selección o confirmación ha caducado. Cancele y elija de nuevo la carpeta.",
47
+ "errorStale": "La sesión o selección ha cambiado. Cancele y elija de nuevo la carpeta.",
48
+ "errorUnavailable": "El servicio de carpetas no está disponible. Pida a un administrador que revise la integración y los servicios de carpetas personales.",
49
+ "errorBusy": "Se ha alcanzado el límite de solicitudes. Espere y vuelva a intentarlo.",
50
+ "errorCanceled": "Solicitud cancelada. Elija de nuevo la carpeta cuando esté listo.",
51
+ "errorInternal": "La solicitud falló. Actualice los accesos antes de volver a intentarlo.",
52
+ "retry": "Reintentar",
53
+ "close": "Cerrar",
54
+ "selection": "Seleccionar carpeta",
55
+ "actionList": "Listar carpetas",
56
+ "actionStat": "Consultar metadatos",
57
+ "actionRead": "Leer archivos",
58
+ "pilotOff": "Piloto de cuentas administradas: desactivado",
59
+ "pilotRestrictions": "Se requiere aprobación del administrador y un proceso verificado de mantenimiento de cuentas. Los cambios de cuenta o una identidad no verificada revocan el acceso y requieren un nuevo inicio de sesión y aprobación. Esta versión no permite activar el piloto.",
60
+ "unavailableTitle": "Aún no disponible",
61
+ "unavailableMessage": "Las autorizaciones de carpetas NAS y las operaciones con archivos aún no están disponibles. Actualmente no se pueden verificar las pruebas nativas de identidad y permisos necesarias.",
62
+ "pilotUnavailable": "El piloto B de cuentas administradas es experimental y no se puede activar.",
63
+ "noUnlock": "Activar la integración o volver a iniciar sesión no desbloquea el acceso a los archivos NAS.",
64
+ "errorUnknownMethod": "Esta versión del paquete no proporciona este método.",
65
+ "errorNativeProof": "La prueba nativa de identidad o permisos necesaria no está disponible. El acceso al NAS permanece cerrado.",
66
+ "errorSession": "La sesión DSM ha caducado. Vuelva a iniciar sesión para restaurar la sesión de la app; el acceso a archivos NAS sigue sin estar disponible.",
67
+ "errorAuthentication": "La autenticación DSM no está disponible. Actualice el estado de la app más tarde.",
68
+ "errorUnsupported": "Las operaciones con archivos NAS no están disponibles en esta compilación.",
69
+ "healthPending": "Revalidación temporal en curso",
70
+ "healthPendingHelp": "La integración se está revalidando temporalmente. Espere y actualice. No se permite ningún acceso nuevo hasta que finalice la verificación.",
71
+ "relaxedRisk": "Con la identidad flexible, las cuentas recreadas con el mismo UID y username pueden conservar las autorizaciones.",
72
+ "relaxedReauthorize": "Un cambio de UID o username invalida todas sus autorizaciones y requiere autorizarlas de nuevo.",
73
+ "relaxedPermissions": "Las operaciones usan su UID y sus grupos, dentro de los permisos del NAS y las carpetas autorizadas. Se deniega el acceso a cuentas deshabilitadas o sin permiso para la aplicación."
74
+ }