@synopackageland/cli 0.6.0 → 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.
- package/CHANGELOG.md +613 -0
- package/README.md +81 -78
- package/dist/add.js +39 -16
- package/dist/authorization-sdk.d.ts +7 -0
- package/dist/authorization-sdk.js +7 -0
- package/dist/build-spk/delegate-scope.d.ts +6 -0
- package/dist/build-spk/delegate-scope.js +34 -0
- package/dist/build-spk/dsm-arch.d.ts +7 -1
- package/dist/build-spk/dsm-arch.js +24 -28
- package/dist/build-spk/dsm-platforms.json +39 -0
- package/dist/build-spk/dsm-version.d.ts +11 -0
- package/dist/build-spk/dsm-version.js +17 -0
- package/dist/build-spk/gateway.d.ts +1 -1
- package/dist/build-spk/gateway.js +2 -2
- package/dist/build-spk/generator.js +30 -5
- package/dist/build-spk/notices.js +4 -1
- package/dist/build-spk/resource-worker.js +3 -0
- package/dist/build-spk/wizard-messages.d.ts +66 -0
- package/dist/build-spk/wizard-messages.js +75 -9
- package/dist/cli.js +30 -18
- package/dist/contract/schema-validate.js +8 -0
- package/dist/contract/validate.js +30 -0
- package/dist/deploy/deploy.d.ts +1 -1
- package/dist/deploy/deploy.js +8 -0
- package/dist/deploy/plan.js +1 -1
- package/dist/deploy/spk-version.js +1 -1
- package/dist/error-registry.js +46 -13
- package/dist/host/dsm-client.d.ts +8 -4
- package/dist/host/dsm-client.js +10 -4
- package/dist/host/types.d.ts +2 -1
- package/dist/info.js +18 -2
- package/dist/init.d.ts +3 -0
- package/dist/init.js +49 -18
- package/dist/package-metadata.d.ts +21 -0
- package/dist/package-metadata.js +101 -0
- package/dist/portal/alias.d.ts +25 -0
- package/dist/portal/alias.js +48 -0
- package/dist/portal/package.d.ts +33 -0
- package/dist/portal/package.js +116 -0
- package/dist/runtime/delegate-contract.d.ts +79 -0
- package/dist/runtime/delegate-contract.js +27 -0
- package/dist/runtime/executor-build.d.ts +1 -1
- package/dist/runtime/executor-build.js +5 -4
- package/dist/runtime/executor-inspect.d.ts +3 -0
- package/dist/runtime/executor-inspect.js +11 -5
- package/dist/runtime/executor-policy.d.ts +12 -0
- package/dist/runtime/executor-policy.js +43 -3
- package/dist/runtime/executor-scope-task.d.ts +4 -0
- package/dist/runtime/executor-scope-task.js +21 -0
- package/dist/runtime/executor-tasks.d.ts +2 -1
- package/dist/runtime/executor-tasks.js +4 -4
- package/dist/skill.js +1 -0
- package/dist/standalone/api-permissions.d.ts +10 -0
- package/dist/standalone/api-permissions.js +19 -2
- package/dist/standalone/background.d.ts +16 -0
- package/dist/standalone/background.js +69 -2
- package/dist/standalone/binary.d.ts +1 -1
- package/dist/standalone/binary.js +22 -8
- package/dist/standalone/build.d.ts +1 -1
- package/dist/standalone/build.js +38 -8
- package/dist/standalone/daemon.d.ts +1 -1
- package/dist/standalone/daemon.js +2 -1
- package/dist/standalone/dsm-window.d.ts +3 -1
- package/dist/standalone/dsm-window.js +72 -15
- package/dist/standalone/inspect-spk.d.ts +9 -1
- package/dist/standalone/inspect-spk.js +119 -26
- package/dist/standalone/lifecycle.js +86 -8
- package/dist/standalone/manifest.d.ts +13 -0
- package/dist/standalone/manifest.js +57 -8
- package/dist/standalone/native-authorization-window.d.ts +2 -0
- package/dist/standalone/native-authorization-window.js +30 -0
- package/dist/standalone/native-layout.d.ts +82 -0
- package/dist/standalone/native-layout.js +377 -0
- package/dist/standalone/native-root-window.d.ts +26 -0
- package/dist/standalone/native-root-window.js +282 -0
- package/dist/standalone/portal-window.d.ts +21 -0
- package/dist/standalone/portal-window.js +155 -0
- package/dist/standalone/portal.d.ts +4 -0
- package/dist/standalone/portal.js +4 -0
- package/dist/standalone/resource.d.ts +5 -3
- package/dist/standalone/resource.js +6 -3
- package/dist/standalone/root-window.js +62 -15
- package/dist/standalone/spk.d.ts +1 -1
- package/dist/standalone/spk.js +25 -7
- package/dist/templates/_daemon/main_test.go +61 -8
- package/dist/templates/_executor/README.md +127 -16
- package/dist/templates/_executor/anchor.go +146 -0
- package/dist/templates/_executor/anchor_test.go +126 -0
- package/dist/templates/_executor/apppriv_review_test.go +1 -1
- package/dist/templates/_executor/cancel_contract_test.go +236 -0
- package/dist/templates/_executor/copy.go +64 -0
- package/dist/templates/_executor/copy_test.go +88 -0
- package/dist/templates/_executor/dsm.go +23 -10
- package/dist/templates/_executor/dsm_test.go +95 -1
- package/dist/templates/_executor/executor.go +260 -49
- package/dist/templates/_executor/executor_test.go +36 -6
- package/dist/templates/_executor/identity.go +27 -1
- package/dist/templates/_executor/identity_kernel_linux_test.go +60 -0
- package/dist/templates/_executor/identity_linux.go +82 -0
- package/dist/templates/_executor/identity_security_test.go +43 -0
- package/dist/templates/_executor/internal/lifecycle/lifecycle.go +5 -0
- package/dist/templates/_executor/internal/lifecycle/lifecycle_test.go +61 -3
- package/dist/templates/_executor/internal/taskscript/boot.sh +9 -9
- package/dist/templates/_executor/internal/taskscript/cmd/main.go +2 -2
- package/dist/templates/_executor/internal/taskscript/control.sh +15 -10
- package/dist/templates/_executor/internal/taskscript/tasks.go +5 -3
- package/dist/templates/_executor/lifecycle_test.go +11 -0
- package/dist/templates/_executor/link_linux.go +28 -0
- package/dist/templates/_executor/long_running_test.go +530 -0
- package/dist/templates/_executor/main.go +72 -20
- package/dist/templates/_executor/move_linux.go +490 -0
- package/dist/templates/_executor/move_linux_test.go +460 -0
- package/dist/templates/_executor/move_validation.go +46 -0
- package/dist/templates/_executor/move_validation_test.go +187 -0
- package/dist/templates/_executor/operations.go +926 -0
- package/dist/templates/_executor/platform_linux.go +24 -173
- package/dist/templates/_executor/platform_linux_test.go +9 -65
- package/dist/templates/_executor/platform_other.go +30 -4
- package/dist/templates/_executor/process.go +3 -0
- package/dist/templates/_executor/records.go +242 -0
- package/dist/templates/_executor/scope_cancel_contract_test.go +91 -0
- package/dist/templates/_executor/scope_client.go +37 -0
- package/dist/templates/_executor/scope_contract.go +12 -0
- package/dist/templates/_executor/selected_scope.go +146 -0
- package/dist/templates/_executor/selected_scope_test.go +186 -0
- package/dist/templates/_executor/status_disabled_test.go +33 -0
- package/dist/templates/_executor/store.go +4 -3
- package/dist/templates/_executor/supervise.go +109 -0
- package/dist/templates/_executor/supervise_test.go +130 -0
- package/dist/templates/_executor/task_race_review_test.go +1 -1
- package/dist/templates/_executor/tasks.go +7 -8
- package/dist/templates/_executor/tasks_review_test.go +1 -1
- package/dist/templates/_executor/tasks_test.go +4 -4
- package/dist/templates/_executor/watch.go +8 -0
- package/dist/templates/_executor/watch_test.go +23 -2
- package/dist/templates/_executor/write_review_linux_test.go +4 -12
- package/dist/templates/_shared/AGENTS.md +129 -0
- package/dist/templates/binary/dsm-package.yaml +24 -0
- package/dist/templates/binary/i18n/messages/de.json +4 -0
- package/dist/templates/binary/i18n/messages/en.json +4 -0
- package/dist/templates/binary/i18n/messages/es.json +4 -0
- package/dist/templates/binary/i18n/messages/fr.json +4 -0
- package/dist/templates/binary/i18n/messages/it.json +4 -0
- package/dist/templates/binary/i18n/messages/ja.json +4 -0
- package/dist/templates/binary/i18n/messages/ko.json +4 -0
- package/dist/templates/binary/i18n/messages/zh-CN.json +4 -0
- package/dist/templates/binary/i18n/messages/zh-TW.json +4 -0
- package/dist/templates/binary/ui/app.js +19 -4
- package/dist/templates/native-authorization/AuthorizationGate.vue +91 -0
- package/dist/templates/native-authorization/i18n/de.json +37 -0
- package/dist/templates/native-authorization/i18n/en.json +37 -0
- package/dist/templates/native-authorization/i18n/es.json +37 -0
- package/dist/templates/native-authorization/i18n/fr.json +37 -0
- package/dist/templates/native-authorization/i18n/index.ts +15 -0
- package/dist/templates/native-authorization/i18n/it.json +37 -0
- package/dist/templates/native-authorization/i18n/ja.json +37 -0
- package/dist/templates/native-authorization/i18n/ko.json +37 -0
- package/dist/templates/native-authorization/i18n/zh-CN.json +37 -0
- package/dist/templates/native-authorization/i18n/zh-TW.json +37 -0
- package/dist/templates/native-go/README.md +43 -10
- package/dist/templates/native-go/backend/cmd/app/main.go +27 -7
- package/dist/templates/native-go/backend/internal/api/entry_test.go +47 -0
- package/dist/templates/native-go/backend/internal/api/permissions_test.go +3 -3
- package/dist/templates/native-go/backend/internal/api/registry.go +11 -0
- package/dist/templates/native-go/backend/internal/api/sdk-permissions.json +14 -1
- package/dist/templates/native-go/backend/internal/api/server.go +18 -5
- package/dist/templates/native-go/backend/internal/app/delegate_config.go +57 -0
- package/dist/templates/native-go/backend/internal/app/delegate_config_test.go +28 -0
- package/dist/templates/native-go/backend/internal/app/portal.go +30 -0
- package/dist/templates/native-go/backend/internal/app/portal_test.go +55 -0
- package/dist/templates/native-go/backend/internal/app/routes.go +8 -2
- package/dist/templates/native-go/backend/internal/background/runner.go +1 -1
- package/dist/templates/native-go/backend/internal/background/store.go +16 -14
- package/dist/templates/native-go/backend/internal/dsm/admin.go +8 -2
- package/dist/templates/native-go/backend/internal/dsm/admin_linux.go +43 -13
- package/dist/templates/native-go/backend/internal/dsm/admin_linux_test.go +56 -0
- package/dist/templates/native-go/backend/internal/dsm/admin_other.go +4 -1
- package/dist/templates/native-go/backend/internal/dsm/apppriv.go +30 -0
- package/dist/templates/native-go/backend/internal/dsm/bridge_file.go +75 -0
- package/dist/templates/native-go/backend/internal/dsm/bridge_file_test.go +57 -0
- package/dist/templates/native-go/backend/internal/dsm/entry.go +177 -0
- package/dist/templates/native-go/backend/internal/dsm/entry_test.go +315 -0
- package/dist/templates/native-go/backend/internal/dsm/native/admin-armv7.elf +0 -0
- package/dist/templates/native-go/backend/internal/dsm/native/apppriv-aarch64.elf +0 -0
- package/dist/templates/native-go/backend/internal/dsm/native/apppriv-armv7.elf +0 -0
- package/dist/templates/native-go/backend/internal/dsm/native/apppriv-x86_64.elf +0 -0
- package/dist/templates/native-go/backend/internal/dsm/native/apppriv_check.c +33 -0
- package/dist/templates/native-go/backend/internal/dsm/native/build.sh +13 -4
- package/dist/templates/native-go/backend/internal/dsm/native/provenance.json +9 -3
- package/dist/templates/native-go/backend/internal/filestation/check_permission.go +71 -0
- package/dist/templates/native-go/backend/internal/filestation/check_permission_test.go +77 -0
- package/dist/templates/native-go/backend/internal/filestation/sdk_policy_test.go +39 -0
- package/dist/templates/native-go/backend/internal/filestation/service.go +1 -1
- package/dist/templates/native-go/backend/internal/portal/portal.go +138 -0
- package/dist/templates/native-go/backend/internal/portal/portal_test.go +89 -0
- package/dist/templates/native-go/dsm-package.yaml +20 -1
- package/dist/templates/native-go/i18n/glossary.json +2 -1
- package/dist/templates/native-go/i18n/messages/de.json +1 -0
- package/dist/templates/native-go/i18n/messages/en.json +1 -0
- package/dist/templates/native-go/i18n/messages/es.json +1 -0
- package/dist/templates/native-go/i18n/messages/fr.json +1 -0
- package/dist/templates/native-go/i18n/messages/it.json +1 -0
- package/dist/templates/native-go/i18n/messages/ja.json +1 -0
- package/dist/templates/native-go/i18n/messages/ko.json +1 -0
- package/dist/templates/native-go/i18n/messages/zh-CN.json +1 -0
- package/dist/templates/native-go/i18n/messages/zh-TW.json +1 -0
- package/dist/templates/native-go/ui/app.css +10 -0
- package/dist/templates/native-go/ui/app.js +11 -1
- package/dist/templates/native-go-delegate/DELEGATE.md +126 -5
- package/dist/templates/native-go-delegate/backend/cmd/background-worker/main.go +7 -0
- package/dist/templates/native-go-delegate/backend/internal/app/delegate.go +11 -1
- package/dist/templates/native-go-delegate/backend/internal/app/delegate_routes_test.go +14 -0
- package/dist/templates/native-go-delegate/backend/internal/background/delegated_moves.go +270 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/admission_recovery_test.go +410 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/cancel_contract_test.go +95 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/client.go +8 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/destination.go +110 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/destination_state.go +117 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/destination_state_test.go +60 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/destination_test.go +116 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/example.go +81 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/example_test.go +91 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/executor_contract_test.go +511 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/files.go +1 -1
- package/dist/templates/native-go-delegate/backend/internal/delegate/long_running_routes.go +92 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/long_running_routes_test.go +99 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/move.go +348 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/move_test.go +351 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/operations_list.go +65 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/operations_list_test.go +114 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/retry_test.go +1 -1
- package/dist/templates/native-go-delegate/backend/internal/delegate/service.go +58 -17
- package/dist/templates/native-go-delegate/backend/internal/delegate/staging.go +121 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/status_disabled_test.go +51 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/testdata/executor_contract.txt +112 -0
- package/dist/templates/native-go-delegate/backend/internal/delegate/transient_contract_test.go +137 -0
- package/dist/templates/native-go-delegate/backend/internal/filestation/files.go +1 -31
- package/dist/templates/native-go-delegate/frontend/src/CapabilityPanels.vue +30 -3
- package/dist/templates/native-go-delegate/frontend/src/delegate/BackgroundSavePanel.vue +113 -0
- package/dist/templates/native-go-delegate/frontend/src/delegate/copy.ts +5 -6
- package/dist/templates/native-go-delegate/frontend/test/background-save.test.ts +121 -0
- package/dist/templates/native-go-delegate/frontend/test/scope-settings.test.ts +49 -0
- package/dist/templates/native-go-delegate/test.sh +1 -0
- package/dist/templates/native-go-jobs/frontend/src/background/i18n/de.json +2 -2
- package/dist/templates/native-go-jobs/frontend/src/background/i18n/en.json +2 -2
- package/dist/templates/native-go-jobs/frontend/src/background/i18n/es.json +12 -12
- package/dist/templates/native-go-jobs/frontend/src/background/i18n/fr.json +4 -4
- package/dist/templates/native-go-jobs/frontend/src/background/i18n/it.json +17 -17
- package/dist/templates/native-go-jobs/frontend/src/background/i18n/ja.json +7 -7
- package/dist/templates/native-go-jobs/frontend/src/background/i18n/ko.json +15 -15
- package/dist/templates/native-go-jobs/frontend/src/background/i18n/zh-CN.json +3 -3
- package/dist/templates/native-go-jobs/frontend/src/background/i18n/zh-TW.json +2 -2
- package/dist/templates/native-go-jobs/frontend/test/background.test.ts +25 -28
- package/dist/templates/native-go-vue/README.md +4 -0
- package/dist/templates/native-go-vue/frontend/package-lock.json +4 -4
- package/dist/templates/native-go-vue/frontend/package.json +1 -1
- package/dist/templates/native-go-vue/frontend/src/App.vue +18 -13
- package/dist/templates/native-go-vue/frontend/src/context.ts +31 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/ExecutorSettings.vue +52 -8
- package/dist/templates/native-go-vue/frontend/src/delegate/catalogs.ts +11 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/copy.test.ts +12 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/copy.ts +4 -4
- package/dist/templates/native-go-vue/frontend/src/delegate/executor-setup.ts +4 -2
- package/dist/templates/native-go-vue/frontend/src/delegate/facade.test.ts +100 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/facade.ts +85 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/de.json +46 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/en.json +12 -2
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/es.json +46 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/fr.json +46 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/it.json +46 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/ja.json +46 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/ko.json +46 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/de.json +42 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/en.json +42 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/es.json +42 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/fr.json +42 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/it.json +42 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/ja.json +42 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/ko.json +42 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/zh-CN.json +42 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/save/zh-TW.json +42 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/zh-CN.json +46 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/i18n/zh-TW.json +15 -5
- package/dist/templates/native-go-vue/frontend/src/delegate/long-running.ts +57 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/save-copy.test.ts +12 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/save-copy.ts +24 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/scoped-picker.test.ts +12 -0
- package/dist/templates/native-go-vue/frontend/src/delegate/scoped-picker.ts +21 -0
- package/dist/templates/native-go-vue/frontend/src/files/files.test.ts +7 -0
- package/dist/templates/native-go-vue/frontend/src/i18n/de.json +20 -0
- package/dist/templates/native-go-vue/frontend/src/i18n/en.json +20 -0
- package/dist/templates/native-go-vue/frontend/src/i18n/es.json +20 -0
- package/dist/templates/native-go-vue/frontend/src/i18n/fr.json +20 -0
- package/dist/templates/native-go-vue/frontend/src/i18n/it.json +20 -0
- package/dist/templates/native-go-vue/frontend/src/i18n/ja.json +20 -0
- package/dist/templates/native-go-vue/frontend/src/i18n/ko.json +20 -0
- package/dist/templates/native-go-vue/frontend/src/i18n/zh-CN.json +20 -0
- package/dist/templates/native-go-vue/frontend/src/i18n/zh-TW.json +20 -0
- package/dist/templates/native-go-vue/frontend/src/i18n.ts +13 -0
- package/dist/templates/native-go-vue/frontend/src/identity/LoginPage.vue +16 -14
- package/dist/templates/native-go-vue/frontend/src/identity/i18n/de.json +27 -0
- package/dist/templates/native-go-vue/frontend/src/identity/i18n/en.json +27 -0
- package/dist/templates/native-go-vue/frontend/src/identity/i18n/es.json +27 -0
- package/dist/templates/native-go-vue/frontend/src/identity/i18n/fr.json +27 -0
- package/dist/templates/native-go-vue/frontend/src/identity/i18n/it.json +27 -0
- package/dist/templates/native-go-vue/frontend/src/identity/i18n/ja.json +27 -0
- package/dist/templates/native-go-vue/frontend/src/identity/i18n/ko.json +27 -0
- package/dist/templates/native-go-vue/frontend/src/identity/i18n/zh-CN.json +27 -0
- package/dist/templates/native-go-vue/frontend/src/identity/i18n/zh-TW.json +27 -0
- package/dist/templates/native-go-vue/frontend/src/identity/i18n.ts +14 -0
- package/dist/templates/native-go-vue/frontend/src/identity/session.test.ts +4 -0
- package/dist/templates/native-go-vue/frontend/src/identity/session.ts +9 -8
- package/dist/templates/native-go-vue/frontend/src/nas/NasPicker.vue +31 -12
- package/dist/templates/native-go-vue/frontend/src/nas/destination.test.ts +48 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/de.json +1 -1
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/en.json +1 -1
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/es.json +10 -10
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/fr.json +1 -1
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/it.json +12 -12
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/ja.json +15 -15
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/ko.json +12 -12
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/zh-CN.json +1 -1
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/files/zh-TW.json +1 -1
- package/dist/templates/native-go-vue/frontend/src/portal/PortalSettings.vue +39 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/fr.json +1 -1
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/ja.json +1 -1
- package/dist/templates/native-go-vue/frontend/test/apps.test.ts +14 -0
- package/dist/templates/native-go-vue/frontend/test/portal-settings.test.ts +71 -0
- package/dist/templates/native-go-vue/frontend/test/shell-i18n.test.ts +50 -0
- package/dist/validate.js +2 -1
- package/package.json +12 -2
- package/schema/package-metadata.schema.json +101 -0
- package/schema/synology-app.schema.json +112 -0
- package/skills/SKILL.md +109 -3
- package/skills/reference/create.md +101 -2
- package/skills/reference/deploy.md +2 -2
- package/skills/reference/files.md +113 -2
- package/skills/reference/identity.md +70 -1
- package/skills/reference/portal.md +17 -0
- package/skills/reference/ui-vue.md +12 -0
- package/templates/_daemon/main_test.go +61 -8
- package/templates/_executor/README.md +127 -16
- package/templates/_executor/anchor.go +146 -0
- package/templates/_executor/anchor_test.go +126 -0
- package/templates/_executor/apppriv_review_test.go +1 -1
- package/templates/_executor/cancel_contract_test.go +236 -0
- package/templates/_executor/copy.go +64 -0
- package/templates/_executor/copy_test.go +88 -0
- package/templates/_executor/dsm.go +23 -10
- package/templates/_executor/dsm_test.go +95 -1
- package/templates/_executor/executor.go +260 -49
- package/templates/_executor/executor_test.go +36 -6
- package/templates/_executor/identity.go +27 -1
- package/templates/_executor/identity_kernel_linux_test.go +60 -0
- package/templates/_executor/identity_linux.go +82 -0
- package/templates/_executor/identity_security_test.go +43 -0
- package/templates/_executor/internal/lifecycle/lifecycle.go +5 -0
- package/templates/_executor/internal/lifecycle/lifecycle_test.go +61 -3
- package/templates/_executor/internal/taskscript/boot.sh +9 -9
- package/templates/_executor/internal/taskscript/cmd/main.go +2 -2
- package/templates/_executor/internal/taskscript/control.sh +15 -10
- package/templates/_executor/internal/taskscript/tasks.go +5 -3
- package/templates/_executor/lifecycle_test.go +11 -0
- package/templates/_executor/link_linux.go +28 -0
- package/templates/_executor/long_running_test.go +530 -0
- package/templates/_executor/main.go +72 -20
- package/templates/_executor/move_linux.go +490 -0
- package/templates/_executor/move_linux_test.go +460 -0
- package/templates/_executor/move_validation.go +46 -0
- package/templates/_executor/move_validation_test.go +187 -0
- package/templates/_executor/operations.go +926 -0
- package/templates/_executor/platform_linux.go +24 -173
- package/templates/_executor/platform_linux_test.go +9 -65
- package/templates/_executor/platform_other.go +30 -4
- package/templates/_executor/process.go +3 -0
- package/templates/_executor/records.go +242 -0
- package/templates/_executor/scope_cancel_contract_test.go +91 -0
- package/templates/_executor/scope_client.go +37 -0
- package/templates/_executor/scope_contract.go +12 -0
- package/templates/_executor/selected_scope.go +146 -0
- package/templates/_executor/selected_scope_test.go +186 -0
- package/templates/_executor/status_disabled_test.go +33 -0
- package/templates/_executor/store.go +4 -3
- package/templates/_executor/supervise.go +109 -0
- package/templates/_executor/supervise_test.go +130 -0
- package/templates/_executor/task_race_review_test.go +1 -1
- package/templates/_executor/tasks.go +7 -8
- package/templates/_executor/tasks_review_test.go +1 -1
- package/templates/_executor/tasks_test.go +4 -4
- package/templates/_executor/watch.go +8 -0
- package/templates/_executor/watch_test.go +23 -2
- package/templates/_executor/write_review_linux_test.go +4 -12
- package/templates/_shared/AGENTS.md +129 -0
- package/templates/binary/dsm-package.yaml +24 -0
- package/templates/binary/i18n/messages/de.json +4 -0
- package/templates/binary/i18n/messages/en.json +4 -0
- package/templates/binary/i18n/messages/es.json +4 -0
- package/templates/binary/i18n/messages/fr.json +4 -0
- package/templates/binary/i18n/messages/it.json +4 -0
- package/templates/binary/i18n/messages/ja.json +4 -0
- package/templates/binary/i18n/messages/ko.json +4 -0
- package/templates/binary/i18n/messages/zh-CN.json +4 -0
- package/templates/binary/i18n/messages/zh-TW.json +4 -0
- package/templates/binary/ui/app.js +19 -4
- package/templates/native-authorization/AuthorizationGate.vue +91 -0
- package/templates/native-authorization/i18n/de.json +37 -0
- package/templates/native-authorization/i18n/en.json +37 -0
- package/templates/native-authorization/i18n/es.json +37 -0
- package/templates/native-authorization/i18n/fr.json +37 -0
- package/templates/native-authorization/i18n/index.ts +15 -0
- package/templates/native-authorization/i18n/it.json +37 -0
- package/templates/native-authorization/i18n/ja.json +37 -0
- package/templates/native-authorization/i18n/ko.json +37 -0
- package/templates/native-authorization/i18n/zh-CN.json +37 -0
- package/templates/native-authorization/i18n/zh-TW.json +37 -0
- package/templates/native-go/README.md +43 -10
- package/templates/native-go/backend/cmd/app/main.go +27 -7
- package/templates/native-go/backend/internal/api/entry_test.go +47 -0
- package/templates/native-go/backend/internal/api/permissions_test.go +3 -3
- package/templates/native-go/backend/internal/api/registry.go +11 -0
- package/templates/native-go/backend/internal/api/sdk-permissions.json +14 -1
- package/templates/native-go/backend/internal/api/server.go +18 -5
- package/templates/native-go/backend/internal/app/delegate_config.go +57 -0
- package/templates/native-go/backend/internal/app/delegate_config_test.go +28 -0
- package/templates/native-go/backend/internal/app/portal.go +30 -0
- package/templates/native-go/backend/internal/app/portal_test.go +55 -0
- package/templates/native-go/backend/internal/app/routes.go +8 -2
- package/templates/native-go/backend/internal/background/runner.go +1 -1
- package/templates/native-go/backend/internal/background/store.go +16 -14
- package/templates/native-go/backend/internal/dsm/admin.go +8 -2
- package/templates/native-go/backend/internal/dsm/admin_linux.go +43 -13
- package/templates/native-go/backend/internal/dsm/admin_linux_test.go +56 -0
- package/templates/native-go/backend/internal/dsm/admin_other.go +4 -1
- package/templates/native-go/backend/internal/dsm/apppriv.go +30 -0
- package/templates/native-go/backend/internal/dsm/bridge_file.go +75 -0
- package/templates/native-go/backend/internal/dsm/bridge_file_test.go +57 -0
- package/templates/native-go/backend/internal/dsm/entry.go +177 -0
- package/templates/native-go/backend/internal/dsm/entry_test.go +315 -0
- package/templates/native-go/backend/internal/dsm/native/admin-armv7.elf +0 -0
- package/templates/native-go/backend/internal/dsm/native/apppriv-aarch64.elf +0 -0
- package/templates/native-go/backend/internal/dsm/native/apppriv-armv7.elf +0 -0
- package/templates/native-go/backend/internal/dsm/native/apppriv-x86_64.elf +0 -0
- package/templates/native-go/backend/internal/dsm/native/apppriv_check.c +33 -0
- package/templates/native-go/backend/internal/dsm/native/build.sh +13 -4
- package/templates/native-go/backend/internal/dsm/native/provenance.json +9 -3
- package/templates/native-go/backend/internal/filestation/check_permission.go +71 -0
- package/templates/native-go/backend/internal/filestation/check_permission_test.go +77 -0
- package/templates/native-go/backend/internal/filestation/sdk_policy_test.go +39 -0
- package/templates/native-go/backend/internal/filestation/service.go +1 -1
- package/templates/native-go/backend/internal/portal/portal.go +138 -0
- package/templates/native-go/backend/internal/portal/portal_test.go +89 -0
- package/templates/native-go/dsm-package.yaml +20 -1
- package/templates/native-go/i18n/glossary.json +2 -1
- package/templates/native-go/i18n/messages/de.json +1 -0
- package/templates/native-go/i18n/messages/en.json +1 -0
- package/templates/native-go/i18n/messages/es.json +1 -0
- package/templates/native-go/i18n/messages/fr.json +1 -0
- package/templates/native-go/i18n/messages/it.json +1 -0
- package/templates/native-go/i18n/messages/ja.json +1 -0
- package/templates/native-go/i18n/messages/ko.json +1 -0
- package/templates/native-go/i18n/messages/zh-CN.json +1 -0
- package/templates/native-go/i18n/messages/zh-TW.json +1 -0
- package/templates/native-go/ui/app.css +10 -0
- package/templates/native-go/ui/app.js +11 -1
- package/templates/native-go-delegate/DELEGATE.md +126 -5
- package/templates/native-go-delegate/backend/cmd/background-worker/main.go +7 -0
- package/templates/native-go-delegate/backend/internal/app/delegate.go +11 -1
- package/templates/native-go-delegate/backend/internal/app/delegate_routes_test.go +14 -0
- package/templates/native-go-delegate/backend/internal/background/delegated_moves.go +270 -0
- package/templates/native-go-delegate/backend/internal/delegate/admission_recovery_test.go +410 -0
- package/templates/native-go-delegate/backend/internal/delegate/cancel_contract_test.go +95 -0
- package/templates/native-go-delegate/backend/internal/delegate/client.go +8 -0
- package/templates/native-go-delegate/backend/internal/delegate/destination.go +110 -0
- package/templates/native-go-delegate/backend/internal/delegate/destination_state.go +117 -0
- package/templates/native-go-delegate/backend/internal/delegate/destination_state_test.go +60 -0
- package/templates/native-go-delegate/backend/internal/delegate/destination_test.go +116 -0
- package/templates/native-go-delegate/backend/internal/delegate/example.go +81 -0
- package/templates/native-go-delegate/backend/internal/delegate/example_test.go +91 -0
- package/templates/native-go-delegate/backend/internal/delegate/executor_contract_test.go +511 -0
- package/templates/native-go-delegate/backend/internal/delegate/files.go +1 -1
- package/templates/native-go-delegate/backend/internal/delegate/long_running_routes.go +92 -0
- package/templates/native-go-delegate/backend/internal/delegate/long_running_routes_test.go +99 -0
- package/templates/native-go-delegate/backend/internal/delegate/move.go +348 -0
- package/templates/native-go-delegate/backend/internal/delegate/move_test.go +351 -0
- package/templates/native-go-delegate/backend/internal/delegate/operations_list.go +65 -0
- package/templates/native-go-delegate/backend/internal/delegate/operations_list_test.go +114 -0
- package/templates/native-go-delegate/backend/internal/delegate/retry_test.go +1 -1
- package/templates/native-go-delegate/backend/internal/delegate/service.go +58 -17
- package/templates/native-go-delegate/backend/internal/delegate/staging.go +121 -0
- package/templates/native-go-delegate/backend/internal/delegate/status_disabled_test.go +51 -0
- package/templates/native-go-delegate/backend/internal/delegate/testdata/executor_contract.txt +112 -0
- package/templates/native-go-delegate/backend/internal/delegate/transient_contract_test.go +137 -0
- package/templates/native-go-delegate/backend/internal/filestation/files.go +1 -31
- package/templates/native-go-delegate/frontend/src/CapabilityPanels.vue +30 -3
- package/templates/native-go-delegate/frontend/src/delegate/BackgroundSavePanel.vue +113 -0
- package/templates/native-go-delegate/frontend/src/delegate/copy.ts +5 -6
- package/templates/native-go-delegate/frontend/test/background-save.test.ts +121 -0
- package/templates/native-go-delegate/frontend/test/scope-settings.test.ts +49 -0
- package/templates/native-go-delegate/test.sh +1 -0
- package/templates/native-go-jobs/frontend/src/background/i18n/de.json +2 -2
- package/templates/native-go-jobs/frontend/src/background/i18n/en.json +2 -2
- package/templates/native-go-jobs/frontend/src/background/i18n/es.json +12 -12
- package/templates/native-go-jobs/frontend/src/background/i18n/fr.json +4 -4
- package/templates/native-go-jobs/frontend/src/background/i18n/it.json +17 -17
- package/templates/native-go-jobs/frontend/src/background/i18n/ja.json +7 -7
- package/templates/native-go-jobs/frontend/src/background/i18n/ko.json +15 -15
- package/templates/native-go-jobs/frontend/src/background/i18n/zh-CN.json +3 -3
- package/templates/native-go-jobs/frontend/src/background/i18n/zh-TW.json +2 -2
- package/templates/native-go-jobs/frontend/test/background.test.ts +25 -28
- package/templates/native-go-vue/README.md +4 -0
- package/templates/native-go-vue/frontend/package-lock.json +4 -4
- package/templates/native-go-vue/frontend/package.json +1 -1
- package/templates/native-go-vue/frontend/src/App.vue +18 -13
- package/templates/native-go-vue/frontend/src/context.ts +31 -0
- package/templates/native-go-vue/frontend/src/delegate/ExecutorSettings.vue +52 -8
- package/templates/native-go-vue/frontend/src/delegate/catalogs.ts +11 -0
- package/templates/native-go-vue/frontend/src/delegate/copy.test.ts +12 -0
- package/templates/native-go-vue/frontend/src/delegate/copy.ts +4 -4
- package/templates/native-go-vue/frontend/src/delegate/executor-setup.ts +4 -2
- package/templates/native-go-vue/frontend/src/delegate/facade.test.ts +100 -0
- package/templates/native-go-vue/frontend/src/delegate/facade.ts +85 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/de.json +46 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/en.json +12 -2
- package/templates/native-go-vue/frontend/src/delegate/i18n/es.json +46 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/fr.json +46 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/it.json +46 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/ja.json +46 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/ko.json +46 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/save/de.json +42 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/save/en.json +42 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/save/es.json +42 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/save/fr.json +42 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/save/it.json +42 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/save/ja.json +42 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/save/ko.json +42 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/save/zh-CN.json +42 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/save/zh-TW.json +42 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/zh-CN.json +46 -0
- package/templates/native-go-vue/frontend/src/delegate/i18n/zh-TW.json +15 -5
- package/templates/native-go-vue/frontend/src/delegate/long-running.ts +57 -0
- package/templates/native-go-vue/frontend/src/delegate/save-copy.test.ts +12 -0
- package/templates/native-go-vue/frontend/src/delegate/save-copy.ts +24 -0
- package/templates/native-go-vue/frontend/src/delegate/scoped-picker.test.ts +12 -0
- package/templates/native-go-vue/frontend/src/delegate/scoped-picker.ts +21 -0
- package/templates/native-go-vue/frontend/src/files/files.test.ts +7 -0
- package/templates/native-go-vue/frontend/src/i18n/de.json +20 -0
- package/templates/native-go-vue/frontend/src/i18n/en.json +20 -0
- package/templates/native-go-vue/frontend/src/i18n/es.json +20 -0
- package/templates/native-go-vue/frontend/src/i18n/fr.json +20 -0
- package/templates/native-go-vue/frontend/src/i18n/it.json +20 -0
- package/templates/native-go-vue/frontend/src/i18n/ja.json +20 -0
- package/templates/native-go-vue/frontend/src/i18n/ko.json +20 -0
- package/templates/native-go-vue/frontend/src/i18n/zh-CN.json +20 -0
- package/templates/native-go-vue/frontend/src/i18n/zh-TW.json +20 -0
- package/templates/native-go-vue/frontend/src/i18n.ts +13 -0
- package/templates/native-go-vue/frontend/src/identity/LoginPage.vue +16 -14
- package/templates/native-go-vue/frontend/src/identity/i18n/de.json +27 -0
- package/templates/native-go-vue/frontend/src/identity/i18n/en.json +27 -0
- package/templates/native-go-vue/frontend/src/identity/i18n/es.json +27 -0
- package/templates/native-go-vue/frontend/src/identity/i18n/fr.json +27 -0
- package/templates/native-go-vue/frontend/src/identity/i18n/it.json +27 -0
- package/templates/native-go-vue/frontend/src/identity/i18n/ja.json +27 -0
- package/templates/native-go-vue/frontend/src/identity/i18n/ko.json +27 -0
- package/templates/native-go-vue/frontend/src/identity/i18n/zh-CN.json +27 -0
- package/templates/native-go-vue/frontend/src/identity/i18n/zh-TW.json +27 -0
- package/templates/native-go-vue/frontend/src/identity/i18n.ts +14 -0
- package/templates/native-go-vue/frontend/src/identity/session.test.ts +4 -0
- package/templates/native-go-vue/frontend/src/identity/session.ts +9 -8
- package/templates/native-go-vue/frontend/src/nas/NasPicker.vue +31 -12
- package/templates/native-go-vue/frontend/src/nas/destination.test.ts +48 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/files/de.json +1 -1
- package/templates/native-go-vue/frontend/src/nas/i18n/files/en.json +1 -1
- package/templates/native-go-vue/frontend/src/nas/i18n/files/es.json +10 -10
- package/templates/native-go-vue/frontend/src/nas/i18n/files/fr.json +1 -1
- package/templates/native-go-vue/frontend/src/nas/i18n/files/it.json +12 -12
- package/templates/native-go-vue/frontend/src/nas/i18n/files/ja.json +15 -15
- package/templates/native-go-vue/frontend/src/nas/i18n/files/ko.json +12 -12
- package/templates/native-go-vue/frontend/src/nas/i18n/files/zh-CN.json +1 -1
- package/templates/native-go-vue/frontend/src/nas/i18n/files/zh-TW.json +1 -1
- package/templates/native-go-vue/frontend/src/portal/PortalSettings.vue +39 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/fr.json +1 -1
- package/templates/native-go-vue/frontend/src/shell/i18n/ja.json +1 -1
- package/templates/native-go-vue/frontend/test/apps.test.ts +14 -0
- package/templates/native-go-vue/frontend/test/portal-settings.test.ts +71 -0
- package/templates/native-go-vue/frontend/test/shell-i18n.test.ts +50 -0
|
@@ -41,3 +41,17 @@ test('failed status loading offers a retry and releases the mounting class',asyn
|
|
|
41
41
|
f.app.unmount();expect(f.root.classList.contains('dsmapp-vue-root')).toBe(false)
|
|
42
42
|
}finally{f.close()}
|
|
43
43
|
})
|
|
44
|
+
test('a portal app shows the Application Portal section on the status page',async()=>{
|
|
45
|
+
const without=fixture('Plain')
|
|
46
|
+
const f=fixture('Portal')
|
|
47
|
+
try{
|
|
48
|
+
await settle();expect(without.root.textContent).not.toContain('Application Portal')
|
|
49
|
+
f.app.unmount()
|
|
50
|
+
const status={state:'active',alias:'portal',url:'https://nas.example/portal/',canManage:false,controlPanel:false,defaultAlias:'portal'} as const
|
|
51
|
+
f.ctx.portal={messages:{title:'Application Portal',link:'Direct link:'},status:vi.fn(async()=>status),apply:vi.fn(),disable:vi.fn(),openControlPanel:vi.fn(),mountPanel:vi.fn()}
|
|
52
|
+
const app=mount(f.root,f.ctx);await settle()
|
|
53
|
+
expect(f.root.textContent).toContain('Application Portal')
|
|
54
|
+
expect(f.root.querySelector('a[href="https://nas.example/portal/"]')).not.toBeNull()
|
|
55
|
+
app.unmount()
|
|
56
|
+
}finally{without.close();f.root.remove()}
|
|
57
|
+
})
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import {expect,test,vi} from 'vitest'
|
|
3
|
+
import {createApp,h,nextTick} from 'vue'
|
|
4
|
+
import {AppRoot} from '@synopackageland/ui'
|
|
5
|
+
import PortalSettings from '../src/portal/PortalSettings.vue'
|
|
6
|
+
import type {PortalAccess,PortalStatus} from '../src/context'
|
|
7
|
+
|
|
8
|
+
const messages={title:'Application Portal',link:'Direct link:',inactive:'Not active.',askAdmin:'Ask an administrator',alias:'Alias',apply:'Apply',disable:'Turn off',advanced:'Advanced',controlPanel:'Open Control Panel',portal_alias_in_use:'Alias in use',portal_unavailable:'DSM refused'}
|
|
9
|
+
const base:PortalStatus={state:'inactive',canManage:false,controlPanel:false,defaultAlias:'my-app'}
|
|
10
|
+
function access(status:PortalStatus,overrides:Partial<PortalAccess>={}):PortalAccess{
|
|
11
|
+
return {messages,status:vi.fn(async()=>status),apply:vi.fn(async()=>status),disable:vi.fn(async()=>status),openControlPanel:vi.fn(),mountPanel:vi.fn(),...overrides}
|
|
12
|
+
}
|
|
13
|
+
async function mount(portal:PortalAccess){
|
|
14
|
+
const root=document.createElement('div');document.body.append(root)
|
|
15
|
+
const app=createApp({render:()=>h(AppRoot,{},()=>h(PortalSettings,{portal}))})
|
|
16
|
+
app.mount(root);await nextTick();await nextTick();await new Promise(r=>setTimeout(r));await nextTick()
|
|
17
|
+
return {root,unmount(){app.unmount();root.remove()}}
|
|
18
|
+
}
|
|
19
|
+
const buttons=(root:HTMLElement)=>[...root.querySelectorAll('button')].map(b=>b.textContent?.trim())
|
|
20
|
+
|
|
21
|
+
test('an ordinary user sees the active link and nothing to change',async()=>{
|
|
22
|
+
const {root,unmount}=await mount(access({...base,state:'active',alias:'my-app',url:'https://nas.example/my-app/'}))
|
|
23
|
+
try{
|
|
24
|
+
expect(root.querySelector('a')?.getAttribute('href')).toBe('https://nas.example/my-app/')
|
|
25
|
+
expect(root.querySelector('input')).toBeNull();expect(root.querySelector('button')).toBeNull()
|
|
26
|
+
}finally{unmount()}
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
test('an ordinary user without an active alias is asked to contact an administrator',async()=>{
|
|
30
|
+
const {root,unmount}=await mount(access({...base,state:'unavailable'}))
|
|
31
|
+
try{
|
|
32
|
+
expect(root.textContent).toContain('Ask an administrator')
|
|
33
|
+
expect(root.querySelector('a,input,button')).toBeNull()
|
|
34
|
+
}finally{unmount()}
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
test('an administrator applies the prefilled alias and sees DSM refusals as portal text',async()=>{
|
|
38
|
+
const apply=vi.fn(async()=>Promise.reject({code:'portal_alias_in_use'}))
|
|
39
|
+
const portal=access({...base,canManage:true},{apply})
|
|
40
|
+
const {root,unmount}=await mount(portal)
|
|
41
|
+
try{
|
|
42
|
+
const input=root.querySelector('input')!
|
|
43
|
+
expect(input.value).toBe('my-app')
|
|
44
|
+
root.querySelector('form')!.dispatchEvent(new Event('submit',{cancelable:true}))
|
|
45
|
+
await new Promise(r=>setTimeout(r));await nextTick()
|
|
46
|
+
expect(apply).toHaveBeenCalledWith('my-app')
|
|
47
|
+
expect(root.querySelector('[role="alert"]')?.textContent).toContain('Alias in use')
|
|
48
|
+
;[...root.querySelectorAll('button')].find(b=>b.textContent?.includes('Advanced'))!.click()
|
|
49
|
+
expect(portal.openControlPanel).toHaveBeenCalled()
|
|
50
|
+
}finally{unmount()}
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
test('an administrator turns an active alias off',async()=>{
|
|
54
|
+
const portal=access({...base,state:'active',alias:'my-app',url:'https://nas.example/my-app/',canManage:true})
|
|
55
|
+
const {root,unmount}=await mount(portal)
|
|
56
|
+
try{
|
|
57
|
+
expect(root.querySelector('a')?.getAttribute('href')).toBe('https://nas.example/my-app/')
|
|
58
|
+
;[...root.querySelectorAll('button')].find(b=>b.textContent?.includes('Turn off'))!.click()
|
|
59
|
+
await nextTick()
|
|
60
|
+
expect(portal.disable).toHaveBeenCalled()
|
|
61
|
+
}finally{unmount()}
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
test('an administrator without DSM portal support gets only the Control Panel shortcut',async()=>{
|
|
65
|
+
const portal=access({...base,state:'unavailable',controlPanel:true})
|
|
66
|
+
const {root,unmount}=await mount(portal)
|
|
67
|
+
try{
|
|
68
|
+
expect(root.querySelector('input')).toBeNull()
|
|
69
|
+
expect(buttons(root)).toEqual(['Open Control Panel'])
|
|
70
|
+
}finally{unmount()}
|
|
71
|
+
})
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
// @vitest-environment-options {"url":"https://nas.test"}
|
|
3
|
+
import {expect,test,vi} from 'vitest'
|
|
4
|
+
import {nextTick} from 'vue'
|
|
5
|
+
import {mount} from '../src/main'
|
|
6
|
+
import type {Context} from '../src/context'
|
|
7
|
+
import {appCopy} from '../src/i18n'
|
|
8
|
+
import {identityCopy} from '../src/identity/i18n'
|
|
9
|
+
async function settle(){for(let i=0;i<20;i++){await Promise.resolve();await nextTick()}}
|
|
10
|
+
const buttons=(root:HTMLElement)=>[...root.querySelectorAll('button')].map(b=>b.textContent?.trim())
|
|
11
|
+
function start(locale:string,call:(method:string)=>Promise<unknown>){
|
|
12
|
+
const ctx={locale,call:vi.fn(call),reopen(){return ()=>{}}} as unknown as Context
|
|
13
|
+
const root=document.createElement('div');document.body.append(root)
|
|
14
|
+
const app=mount(root,ctx)
|
|
15
|
+
return {root,close(){app.unmount();root.remove()}}
|
|
16
|
+
}
|
|
17
|
+
test('the status page and its errors follow the DSM language',async()=>{
|
|
18
|
+
const copy=appCopy('ger')
|
|
19
|
+
const {root,close}=start('de',async method=>{
|
|
20
|
+
if(method==='app.status')return {package:'Pkg',version:'1',user:'admin',admin:true}
|
|
21
|
+
if(method==='greeting.get')throw {code:'admin_required'}
|
|
22
|
+
throw {code:'unknown_method'}
|
|
23
|
+
})
|
|
24
|
+
try{
|
|
25
|
+
await settle()
|
|
26
|
+
expect(buttons(root)).toContain(copy.refresh)
|
|
27
|
+
expect(root.textContent).toContain(copy.statusTitle)
|
|
28
|
+
expect(root.textContent).toContain(copy.greeting)
|
|
29
|
+
expect(root.textContent).toContain(copy.errors.admin_required)
|
|
30
|
+
expect(root.querySelector('[aria-label]')?.getAttribute('aria-label')).not.toBe('Package settings')
|
|
31
|
+
}finally{close()}
|
|
32
|
+
})
|
|
33
|
+
test('unknown failures name the code in the DSM language',()=>{
|
|
34
|
+
expect(appCopy('ja').errors.request_failed).toContain('{code}')
|
|
35
|
+
})
|
|
36
|
+
test('the sign-in page and its session notices follow the DSM language',async()=>{
|
|
37
|
+
const copy=identityCopy('jpn')
|
|
38
|
+
const {root,close}=start('ja',async method=>{
|
|
39
|
+
if(method==='identity.status')return {enabled:true}
|
|
40
|
+
if(method==='identity.session')return {user:'alice',uid:'1',expiresAt:new Date(Date.now()-1000).toISOString()}
|
|
41
|
+
throw {code:'session_required'}
|
|
42
|
+
})
|
|
43
|
+
try{
|
|
44
|
+
await settle()
|
|
45
|
+
expect(root.textContent).toContain(copy.title)
|
|
46
|
+
expect(buttons(root)).toEqual(expect.arrayContaining([copy.signIn,copy.continueDSM]))
|
|
47
|
+
expect(root.querySelector('[role="status"]')?.textContent).toBe(copy.notices.expired)
|
|
48
|
+
expect(root.textContent).not.toMatch(/Sign in|Account|Password|session/)
|
|
49
|
+
}finally{close()}
|
|
50
|
+
})
|
package/dist/validate.js
CHANGED
|
@@ -6,6 +6,7 @@ import { validateContract } from "./contract/validate.js";
|
|
|
6
6
|
import { findListingUnsupportedInstallTypes } from "./contract/unsupported-types.js";
|
|
7
7
|
import { classifyComposeRoute, collectComposeInterpolations, collectVolumeSourceInterpolations, loadCompose, validateAdminPortMapping, validateComposeHostBinds, validateComposeNumericCommandArgs, validateComposeRunAs, validateComposeSecurity, validateGatewayPortLoopback, } from "./compose/analyze.js";
|
|
8
8
|
import { usesAuthGateway } from "./contract/web-launch.js";
|
|
9
|
+
import { isNativeLayout, loadNativeLayout } from "./standalone/native-layout.js";
|
|
9
10
|
import { loadStandaloneManifest } from "./standalone/manifest.js";
|
|
10
11
|
import { COMPOSE_FILENAME, CONTRACT_FILENAME, DSM_PACKAGE_FILENAME, } from "./discovery.js";
|
|
11
12
|
import { declaredPrivilegeFlags } from "./compose/privilege.js";
|
|
@@ -26,7 +27,7 @@ export function validateProject(project, options = {}) {
|
|
|
26
27
|
}] };
|
|
27
28
|
}
|
|
28
29
|
if (hasStandalone) {
|
|
29
|
-
const loaded = loadStandaloneManifest(project.root);
|
|
30
|
+
const loaded = isNativeLayout(project.root) ? loadNativeLayout(project.root) : loadStandaloneManifest(project.root);
|
|
30
31
|
return loaded.ok ? { ok: true, errors: [] } : { ok: false, errors: loaded.errors.map(error => ({
|
|
31
32
|
...error, span: { file: DSM_PACKAGE_FILENAME, line: 1, column: 1 },
|
|
32
33
|
suggestion: "請修正 dsm-package.yaml 的 schema 2 欄位與能力宣告。",
|
package/package.json
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synopackageland/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Syno Package Land Developer Kit CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"synopkgland": "./dist/bin.js"
|
|
8
8
|
},
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=22.12"
|
|
11
|
+
},
|
|
9
12
|
"files": [
|
|
10
13
|
"dist",
|
|
14
|
+
"CHANGELOG.md",
|
|
11
15
|
"templates",
|
|
12
16
|
"schema",
|
|
13
17
|
"skills"
|
|
@@ -32,5 +36,11 @@
|
|
|
32
36
|
"access": "public",
|
|
33
37
|
"registry": "https://registry.npmjs.org"
|
|
34
38
|
},
|
|
35
|
-
"license": "MIT"
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"exports": {
|
|
41
|
+
"./authorization-sdk": "./dist/authorization-sdk.js",
|
|
42
|
+
"./dist/*": "./dist/*",
|
|
43
|
+
"./package.json": "./package.json",
|
|
44
|
+
"./native-layout": "./dist/standalone/native-layout.js"
|
|
45
|
+
}
|
|
36
46
|
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"type": "object",
|
|
4
|
+
"additionalProperties": false,
|
|
5
|
+
"properties": {
|
|
6
|
+
"changelog": {
|
|
7
|
+
"oneOf": [
|
|
8
|
+
{
|
|
9
|
+
"type": "string",
|
|
10
|
+
"maxLength": 16000
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"type": "object",
|
|
14
|
+
"maxProperties": 32,
|
|
15
|
+
"additionalProperties": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"maxLength": 16000
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"contact_email": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"maxLength": 16000,
|
|
25
|
+
"pattern": "^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$"
|
|
26
|
+
},
|
|
27
|
+
"support_email": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"maxLength": 16000,
|
|
30
|
+
"pattern": "^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$"
|
|
31
|
+
},
|
|
32
|
+
"homepage": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"maxLength": 16000,
|
|
35
|
+
"pattern": "^https?://"
|
|
36
|
+
},
|
|
37
|
+
"source_url": {
|
|
38
|
+
"type": "string",
|
|
39
|
+
"maxLength": 16000,
|
|
40
|
+
"pattern": "^https?://"
|
|
41
|
+
},
|
|
42
|
+
"issues_url": {
|
|
43
|
+
"type": "string",
|
|
44
|
+
"maxLength": 16000,
|
|
45
|
+
"pattern": "^https?://"
|
|
46
|
+
},
|
|
47
|
+
"license": {
|
|
48
|
+
"type": "string",
|
|
49
|
+
"maxLength": 16000
|
|
50
|
+
},
|
|
51
|
+
"maintainer_url": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"maxLength": 16000,
|
|
54
|
+
"pattern": "^https?://"
|
|
55
|
+
},
|
|
56
|
+
"distributor": {
|
|
57
|
+
"type": "string",
|
|
58
|
+
"maxLength": 16000
|
|
59
|
+
},
|
|
60
|
+
"distributor_url": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"maxLength": 16000,
|
|
63
|
+
"pattern": "^https?://"
|
|
64
|
+
},
|
|
65
|
+
"support_url": {
|
|
66
|
+
"type": "string",
|
|
67
|
+
"maxLength": 16000,
|
|
68
|
+
"pattern": "^(https?://|mailto:)"
|
|
69
|
+
},
|
|
70
|
+
"helpurl": {
|
|
71
|
+
"type": "string",
|
|
72
|
+
"maxLength": 16000,
|
|
73
|
+
"pattern": "^https?://"
|
|
74
|
+
},
|
|
75
|
+
"long_description": {
|
|
76
|
+
"oneOf": [
|
|
77
|
+
{
|
|
78
|
+
"type": "string",
|
|
79
|
+
"maxLength": 16000
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"type": "object",
|
|
83
|
+
"maxProperties": 32,
|
|
84
|
+
"additionalProperties": {
|
|
85
|
+
"type": "string",
|
|
86
|
+
"maxLength": 16000
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
"screenshots": {
|
|
92
|
+
"type": "array",
|
|
93
|
+
"maxItems": 12,
|
|
94
|
+
"items": {
|
|
95
|
+
"type": "string",
|
|
96
|
+
"pattern": "^https?://",
|
|
97
|
+
"maxLength": 2048
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -118,6 +118,18 @@
|
|
|
118
118
|
"pattern": "^(?:[A-Za-z0-9._-]{1,64}|[A-Za-z0-9._-]{1,64}\\\\[A-Za-z0-9._-](?:[A-Za-z0-9._ -]{0,126}[A-Za-z0-9._-])?|[A-Za-z0-9._-](?:[A-Za-z0-9._ -]{0,126}[A-Za-z0-9._-])?@[A-Za-z0-9._-]{1,64})$(?![\\s\\S])"
|
|
119
119
|
},
|
|
120
120
|
"description": "DSM group names allowed in; only with access: dsm-groups."
|
|
121
|
+
},
|
|
122
|
+
"portal": {
|
|
123
|
+
"type": "object",
|
|
124
|
+
"properties": {
|
|
125
|
+
"alias": {
|
|
126
|
+
"type": "string",
|
|
127
|
+
"pattern": "^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$",
|
|
128
|
+
"description": "Default DSM Application Portal alias (https://<nas>/<alias>/). Omit to use the package name. An administrator still applies it."
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
"additionalProperties": false,
|
|
132
|
+
"description": "Register the App in DSM Control Panel > Login Portal > Applications. Needs launch: dsm-window behind the DSM gateway (access other than public) and os_min_ver 7.3.2-86009 or later. Registration alone exposes nothing."
|
|
121
133
|
}
|
|
122
134
|
},
|
|
123
135
|
"additionalProperties": true
|
|
@@ -149,6 +161,106 @@
|
|
|
149
161
|
"type": "boolean"
|
|
150
162
|
}
|
|
151
163
|
}
|
|
164
|
+
},
|
|
165
|
+
"metadata": {
|
|
166
|
+
"type": "object",
|
|
167
|
+
"additionalProperties": false,
|
|
168
|
+
"properties": {
|
|
169
|
+
"changelog": {
|
|
170
|
+
"oneOf": [
|
|
171
|
+
{
|
|
172
|
+
"type": "string",
|
|
173
|
+
"maxLength": 16000
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"type": "object",
|
|
177
|
+
"maxProperties": 32,
|
|
178
|
+
"additionalProperties": {
|
|
179
|
+
"type": "string",
|
|
180
|
+
"maxLength": 16000
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
]
|
|
184
|
+
},
|
|
185
|
+
"contact_email": {
|
|
186
|
+
"type": "string",
|
|
187
|
+
"maxLength": 16000,
|
|
188
|
+
"pattern": "^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$"
|
|
189
|
+
},
|
|
190
|
+
"support_email": {
|
|
191
|
+
"type": "string",
|
|
192
|
+
"maxLength": 16000,
|
|
193
|
+
"pattern": "^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$"
|
|
194
|
+
},
|
|
195
|
+
"homepage": {
|
|
196
|
+
"type": "string",
|
|
197
|
+
"maxLength": 16000,
|
|
198
|
+
"pattern": "^https?://"
|
|
199
|
+
},
|
|
200
|
+
"source_url": {
|
|
201
|
+
"type": "string",
|
|
202
|
+
"maxLength": 16000,
|
|
203
|
+
"pattern": "^https?://"
|
|
204
|
+
},
|
|
205
|
+
"issues_url": {
|
|
206
|
+
"type": "string",
|
|
207
|
+
"maxLength": 16000,
|
|
208
|
+
"pattern": "^https?://"
|
|
209
|
+
},
|
|
210
|
+
"license": {
|
|
211
|
+
"type": "string",
|
|
212
|
+
"maxLength": 16000
|
|
213
|
+
},
|
|
214
|
+
"maintainer_url": {
|
|
215
|
+
"type": "string",
|
|
216
|
+
"maxLength": 16000,
|
|
217
|
+
"pattern": "^https?://"
|
|
218
|
+
},
|
|
219
|
+
"distributor": {
|
|
220
|
+
"type": "string",
|
|
221
|
+
"maxLength": 16000
|
|
222
|
+
},
|
|
223
|
+
"distributor_url": {
|
|
224
|
+
"type": "string",
|
|
225
|
+
"maxLength": 16000,
|
|
226
|
+
"pattern": "^https?://"
|
|
227
|
+
},
|
|
228
|
+
"support_url": {
|
|
229
|
+
"type": "string",
|
|
230
|
+
"maxLength": 16000,
|
|
231
|
+
"pattern": "^(https?://|mailto:)"
|
|
232
|
+
},
|
|
233
|
+
"helpurl": {
|
|
234
|
+
"type": "string",
|
|
235
|
+
"maxLength": 16000,
|
|
236
|
+
"pattern": "^https?://"
|
|
237
|
+
},
|
|
238
|
+
"long_description": {
|
|
239
|
+
"oneOf": [
|
|
240
|
+
{
|
|
241
|
+
"type": "string",
|
|
242
|
+
"maxLength": 16000
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
"type": "object",
|
|
246
|
+
"maxProperties": 32,
|
|
247
|
+
"additionalProperties": {
|
|
248
|
+
"type": "string",
|
|
249
|
+
"maxLength": 16000
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
]
|
|
253
|
+
},
|
|
254
|
+
"screenshots": {
|
|
255
|
+
"type": "array",
|
|
256
|
+
"maxItems": 12,
|
|
257
|
+
"items": {
|
|
258
|
+
"type": "string",
|
|
259
|
+
"pattern": "^https?://",
|
|
260
|
+
"maxLength": 2048
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
152
264
|
}
|
|
153
265
|
},
|
|
154
266
|
"additionalProperties": true
|
package/skills/SKILL.md
CHANGED
|
@@ -5,15 +5,15 @@ description: Initialize, extend, check, build, inspect, and deploy Synology appl
|
|
|
5
5
|
|
|
6
6
|
# Independent Synology SPKs
|
|
7
7
|
|
|
8
|
-
Use this guide to initialize, build and inspect own applications or upstream OSS as independent packages. 依已實作能力區分 DSM session 檔案、私有 jobs 與 App 登入;delegate
|
|
8
|
+
Use this guide to initialize, build and inspect own applications or upstream OSS as independent packages. 依已實作能力區分 DSM session 檔案、私有 jobs 與 App 登入;delegate 已實作並隨 CLI 提供固定操作的離線委託(預設 `files.moveFromStaging`);共用 delegate/rootOps executor 的完整裝置生命週期驗收仍待完成,不得宣稱已通過;支援邊界依 delegate guide/support matrix,禁止發明新的身分平台。
|
|
9
9
|
|
|
10
10
|
Start with `synopkgland init -t native-go`, `synopkgland init -t binary`, or `synopkgland init -t compose`. Read reference/create.md or reference/wrap.md, then reference/deploy.md. Native CGI session checks belong to the package. Container authentication belongs to upstream; fixed service credentials govern mounted data access.
|
|
11
11
|
|
|
12
12
|
Never install, uninstall, publish or modify NAS data without task authorization. Prefer check, inspect and deploy --dry-run for reviewable artifacts.
|
|
13
13
|
|
|
14
|
-
Native projects use schema 2 capabilities and `--with files,jobs,login,root-ops`; use `add` for existing projects. Prefer `check --json`, `build --json`, `inspect <spk> --json`, `deploy --dry-run --json`, and `status --host <profile> --json` for structured results. Read the conflict policy in reference/create.md before adding overlays.
|
|
14
|
+
Native projects use schema 2 capabilities and `--with files,jobs,login,root-ops,delegate`; use `add` for existing projects. Prefer `check --json`, `build --json`, `inspect <spk> --json`, `deploy --dry-run --json`, and `status --host <profile> --json` for structured results. Read the conflict policy in reference/create.md before adding overlays.
|
|
15
15
|
|
|
16
|
-
Read reference/files.md and reference/identity.md for capability boundaries. RootOps
|
|
16
|
+
Read reference/portal.md before declaring or changing a DSM Application Portal alias (`add portal`); DSM owns the saved setting. Read reference/files.md and reference/identity.md for capability boundaries. RootOps and delegate share one-time protected executor boot/control setup with digest approval. Existing native products can explicitly use the separate authorization-sdk build-time adapter; do not mix its tasks with generated executor capabilities. App sessions alone do not grant NAS file authority.
|
|
17
17
|
|
|
18
18
|
Read [reference/ui-vue.md](reference/ui-vue.md) when editing Vue components in the native-go Vue template; use the installed SDK contracts, keep DSM embedding boundaries, and verify the actual app.
|
|
19
19
|
|
|
@@ -23,3 +23,109 @@ For UI discovery, run `npx --no syno-pkg-land-ui catalog --json` and
|
|
|
23
23
|
`npx --no syno-pkg-land-ui describe Button --json` from the installed frontend.
|
|
24
24
|
Read its prompt and exported Vue docs/types before choosing component APIs.
|
|
25
25
|
Use `syno-pkg-land-ui` directly in npm scripts; keep AI guidance version-independent.
|
|
26
|
+
|
|
27
|
+
For existing native products, schema 2 `backend: {kind: native}` preserves project-owned payload/metadata, prepare/compile argv hooks and pinned toolkits. See the native-layout guide; run `check`, `build`, then `inspect <spk>` locally. Keep lifecycle/systemd as the package account and preserve product-owned digest approval/revocation. Native layouts do not opt into generated Go capabilities.
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
## Permanent destination integration
|
|
31
|
+
|
|
32
|
+
`init --with delegate` / `add delegate` default to `operations: [files.moveFromStaging]`,
|
|
33
|
+
`destinations: [save]`, `lifetime: until-revoked`, `scope: install-selected`. Existing legacy
|
|
34
|
+
TTL declarations retain their 1–3600 second service / 30-day wire ceiling and
|
|
35
|
+
64 MiB / 60-second URL example. Do not apply those limits to the new move API.
|
|
36
|
+
Delegate can coexist with daemon; ordinary standalone jobs cannot. Preserve
|
|
37
|
+
App business route floors. Binary/compose remain unsupported.
|
|
38
|
+
|
|
39
|
+
Use File Station `/home[/...]`, never `/homes/<user>`. The SDK destination picker
|
|
40
|
+
selection itself grants access after fresh DSM session/UID/write verification,
|
|
41
|
+
without a second consent dialog. Ordinary and administrator subjects use their
|
|
42
|
+
own nonzero UID/current groups, never root. An online App can create an in-scope
|
|
43
|
+
grant using a valid session; there is no trusted external consent or notification.
|
|
44
|
+
|
|
45
|
+
Use the default `createBackgroundSaveFacade(ctx)` / CapabilityPanels management
|
|
46
|
+
page. `delegate.status` exposes verified `disabled` and manifest mode; missing
|
|
47
|
+
protected evidence must not imply enabled. `delegate.operations.list` accepts
|
|
48
|
+
only `{}`, uses the backend move mirrors, and returns the caller's username+UID
|
|
49
|
+
operations only, including for admins. Mirrors are not completion receipts:
|
|
50
|
+
query original `delegate.operations.get` and show Saved only for committed with
|
|
51
|
+
a receipt. Cancel by the same reference; revoke by grant ID. Never resubmit
|
|
52
|
+
uncertain/interrupted work. Admin disable is protected and revokes grants;
|
|
53
|
+
enable/mailbox start does not resurrect them. Keep IDs, never session credentials.
|
|
54
|
+
|
|
55
|
+
App-owned daemon completion and scheduled CSV export call configured Go
|
|
56
|
+
`Service.MoveFromStaging` with `delegation_id`, stable `job_id`, private relative
|
|
57
|
+
`staging`, `name`, `size`. No owner/UID selector. Bounds: 16 GiB/file, queued16,
|
|
58
|
+
active1/package, 24-hour attempt, 5-second revalidation ticks (one check at a time, 30-second complete-check deadline; proven timeouts retain private copying, publication still revalidates), 10 MiB operation records,
|
|
59
|
+
50 MiB audit. Scope is a usage restriction, not hard subtree confinement.
|
|
60
|
+
Local production-executor fixtures use fake DSM/peer/bulk writer; do not claim
|
|
61
|
+
NAS ACL, actual writer UID, logout/reboot or full lifecycle acceptance from them.
|
|
62
|
+
Gopeed product wiring remains a separate task.
|
|
63
|
+
|
|
64
|
+
Admission recovery (per job): on `EXECUTOR_UNAVAILABLE`, `EXECUTOR_TIMEOUT`,
|
|
65
|
+
`EXECUTOR_PROTOCOL`, `canceled`, `EXECUTOR_PAUSED`, `queue-full`,
|
|
66
|
+
`STORAGE_ERROR`, `ADMISSION_PENDING`, `jobs_busy` or `jobs_unavailable` (the
|
|
67
|
+
package journal was busy or failed transiently; a caller deadline or cancel
|
|
68
|
+
spent waiting for it is `canceled`), call `MoveFromStaging` again later with
|
|
69
|
+
the same exact params. It queries the original reference first and re-sends
|
|
70
|
+
admission only when the executor does not know it and the pinned source is
|
|
71
|
+
unchanged; executor tuple deduplication keeps one operation, so a lost reply or a
|
|
72
|
+
racing caller never copies twice. At most 10 possibly-delivered sends, 2 s
|
|
73
|
+
backoff doubling to 5 min; the worker sweep does the same. Terminal, do not
|
|
74
|
+
retry: `APP_DENIED`, `DELEGATION_DENIED`, `operation-conflict`, `disabled`,
|
|
75
|
+
`SCOPE_DENIED` and other executor refusals, `STAGING_CHANGED`,
|
|
76
|
+
`ADMISSION_EXHAUSTED`, `spool_unsafe` and `journal_corrupt` (repair the package
|
|
77
|
+
spool first), and `operation-not-found` for an accepted operation.
|
|
78
|
+
Never change job/grant IDs, delete mirrors or call the socket directly to retry.
|
|
79
|
+
|
|
80
|
+
Cancellation (per job): `CancelOperation` / `delegate.operations.cancel` with the
|
|
81
|
+
original ref is idempotent; repeat it with the same ref after any retryable
|
|
82
|
+
error or a lost reply. A reply `queued`→`canceled` is final at once. A copy in
|
|
83
|
+
flight answers `copying` with code `CANCEL_REQUESTED`: the cancel is accepted and
|
|
84
|
+
durable, not finished; poll `OperationStatus` on the same ref until terminal
|
|
85
|
+
(repeating the cancel is harmless). `canceled` (`OPERATION_CANCELED`) guarantees the writer
|
|
86
|
+
stopped, its part file is removed, nothing was published and staging is kept; it
|
|
87
|
+
stays canceled across executor crash, package stop/start and logout. Revoke, scope change and disable store their reason (`grant-revoked`,
|
|
88
|
+
`scope-changed`, `integration-disabled`) the same way: a copy in flight answers
|
|
89
|
+
`CANCEL_REQUESTED` with it and settles `canceled` with it across a restart. A
|
|
90
|
+
copy the executor stops without a cancel ends `interrupted`/`EXECUTOR_PAUSED`
|
|
91
|
+
(`interrupted`/`interrupted` after a crash), never `WRITE_FAILED`. `committed`
|
|
92
|
+
means publication won the race: the file stays (cancel never removes it) and only
|
|
93
|
+
the app record may be dropped. `uncertain` means a publish attempt failed before
|
|
94
|
+
the cancel; keep querying. A cancel of a ref the executor has not admitted yet
|
|
95
|
+
(reserved/sent mirror) returns `canceled` and leaves a tombstone, so a late or
|
|
96
|
+
recovered admission of that ref returns `canceled` and never copies; a producer
|
|
97
|
+
cancel is also written to the mirror first, so `MoveFromStaging` and the worker
|
|
98
|
+
sweep forward the cancel instead of admitting it.
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
### Install-selected scope and the destination API
|
|
102
|
+
|
|
103
|
+
- The DSM install wizard dynamically lists local shares (`SYNO.Core.Share list`
|
|
104
|
+
via `api_store`) and offers home. It saves only a package-owned pre-selection
|
|
105
|
+
in `var/delegate-install.json`; never trust that file for authority.
|
|
106
|
+
- The existing administrator PasswordConfirm form displays this pre-selection
|
|
107
|
+
at first enable. `ctx.executor.authorize(password, selectedScope)` confirms it
|
|
108
|
+
through a pinned, exact-readback one-time root task. Settings changes use the
|
|
109
|
+
same form/password path; no App CGI route may set protected scope directly.
|
|
110
|
+
- The executor trusts `/usr/local/etc/synopkgland/<pkg>/delegations/selected-scope.record`
|
|
111
|
+
only. Its scope/generation are runtime protected state; shipped policy pins
|
|
112
|
+
lock the selection mode and operations. Changes revoke old grants and cancel
|
|
113
|
+
pending writes. Change-away-and-back never revives an old grant.
|
|
114
|
+
- Follow `selection` from verified `delegate.status` / `sdk.destination(key)`.
|
|
115
|
+
If the draft differs, display the difference and follow the protected value.
|
|
116
|
+
Home and fixed `shared:<name>` manifests stay compatible.
|
|
117
|
+
- Frontend: `const sdk = createBackgroundSaveFacade(ctx); const current = await
|
|
118
|
+
sdk.destination('save')` returns typed `{key, selection, destination, status}`.
|
|
119
|
+
`selection` contains `{scope, root, generation}`; `destination` is this caller's
|
|
120
|
+
grant or null. Handle active/missing/reselection-required/needs-scope-confirmation/disabled.
|
|
121
|
+
- Go: `Service.Destination(ctx, caller, request, key)` verifies the fresh DSM
|
|
122
|
+
session and username+UID. Capture its active grant ID into the App job. The
|
|
123
|
+
offline producer uses existing `Service.MoveFromStaging`; no user/UID selector,
|
|
124
|
+
cookie, token, or browser path cache. Executor revalidates at use/publication.
|
|
125
|
+
- The generated Background saves page includes a working **Save example file**
|
|
126
|
+
(`sdk.exportExample({key, job_id})`, `delegate.example.export`). Go
|
|
127
|
+
`ExportExample` creates a private JSON file, calls `MoveFromStaging` once, and
|
|
128
|
+
repeats the original request on repeated IDs. Review `example.go` to
|
|
129
|
+
adapt a real producer; show Saved only from a protected committed receipt.
|
|
130
|
+
- Wizard support is measured on vt-nas DSM 7.4 via a session-only SSH local
|
|
131
|
+
forward. This is not proof of other DSM releases or full writer/reboot behavior.
|