@synopackageland/cli 0.4.1 → 0.5.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/README.md +7 -3
- package/dist/build-spk/delete-app-data.d.ts +27 -7
- package/dist/build-spk/delete-app-data.js +35 -34
- package/dist/build-spk/dsm-arch.d.ts +6 -1
- package/dist/build-spk/dsm-arch.js +25 -1
- package/dist/build-spk/dsm-version.d.ts +14 -0
- package/dist/build-spk/dsm-version.js +47 -0
- package/dist/build-spk/gateway.d.ts +31 -0
- package/dist/build-spk/gateway.js +55 -0
- package/dist/build-spk/generator.d.ts +5 -0
- package/dist/build-spk/generator.js +103 -107
- package/dist/build-spk/install-wizard.d.ts +20 -0
- package/dist/build-spk/install-wizard.js +76 -0
- package/dist/build-spk/native-lifecycle.d.ts +5 -0
- package/dist/build-spk/native-lifecycle.js +12 -2
- package/dist/build-spk/resource-worker.d.ts +9 -4
- package/dist/build-spk/resource-worker.js +15 -6
- package/dist/build-spk/share-combobox.d.ts +3 -0
- package/dist/build-spk/share-combobox.js +27 -0
- package/dist/build-spk/uninstall-wizard.d.ts +14 -0
- package/dist/build-spk/uninstall-wizard.js +33 -0
- package/dist/build-spk/wizard-i18n.d.ts +18 -0
- package/dist/build-spk/wizard-i18n.js +38 -0
- package/dist/build-spk/wizard-messages.d.ts +388 -0
- package/dist/build-spk/wizard-messages.js +387 -0
- package/dist/cli.js +130 -30
- package/dist/compose/analyze.d.ts +20 -0
- package/dist/compose/analyze.js +75 -11
- package/dist/contract/validate.js +33 -1
- package/dist/contract/web-launch.d.ts +22 -0
- package/dist/contract/web-launch.js +37 -0
- package/dist/deploy/deploy.d.ts +3 -0
- package/dist/deploy/deploy.js +11 -2
- package/dist/error-registry.js +60 -1
- package/dist/host/open-url.d.ts +2 -0
- package/dist/host/open-url.js +4 -1
- package/dist/images/pin.d.ts +52 -0
- package/dist/images/pin.js +249 -0
- package/dist/init.d.ts +27 -3
- package/dist/init.js +104 -15
- package/dist/inspect.d.ts +3 -0
- package/dist/inspect.js +15 -3
- package/dist/standalone/background.d.ts +21 -0
- package/dist/standalone/background.js +52 -0
- package/dist/standalone/binary.d.ts +1 -0
- package/dist/standalone/binary.js +1 -1
- package/dist/standalone/build.d.ts +2 -0
- package/dist/standalone/build.js +38 -6
- package/dist/standalone/dsm-window.js +2 -2
- package/dist/standalone/helper-inventory.d.ts +15 -0
- package/dist/standalone/helper-inventory.js +9 -0
- package/dist/standalone/helper.d.ts +1 -0
- package/dist/standalone/helper.js +28 -10
- package/dist/standalone/host-adapter.d.ts +1 -1
- package/dist/standalone/host-adapter.js +33 -15
- package/dist/standalone/host-file-navigation.d.ts +7 -0
- package/dist/standalone/host-file-navigation.js +172 -0
- package/dist/standalone/inspect-helper.js +9 -4
- package/dist/standalone/inspect-spk.d.ts +1 -1
- package/dist/standalone/inspect-spk.js +200 -7
- package/dist/standalone/job-diagnostics.d.ts +1 -0
- package/dist/standalone/job-diagnostics.js +49 -0
- package/dist/standalone/lifecycle.js +12 -2
- package/dist/standalone/manifest.d.ts +15 -2
- package/dist/standalone/manifest.js +37 -6
- package/dist/standalone/native-layout.d.ts +74 -0
- package/dist/standalone/native-layout.js +318 -0
- package/dist/standalone/resource.d.ts +11 -0
- package/dist/standalone/resource.js +13 -0
- package/dist/standalone/root-window.d.ts +3 -1
- package/dist/standalone/root-window.js +156 -38
- package/dist/standalone/shared-folder.d.ts +39 -0
- package/dist/standalone/shared-folder.js +141 -0
- package/dist/standalone/spk.d.ts +2 -0
- package/dist/standalone/spk.js +33 -3
- package/dist/standalone/worker-contract-json.d.ts +8 -0
- package/dist/standalone/worker-contract-json.js +141 -0
- package/dist/standalone/worker-contract.d.ts +189 -0
- package/dist/standalone/worker-contract.js +175 -0
- package/dist/standalone/worker-registry.d.ts +40 -0
- package/dist/standalone/worker-registry.js +167 -0
- package/dist/templates/_daemon/go.mod +2 -0
- package/dist/templates/_gateway/auth.go +101 -0
- package/dist/templates/_gateway/auth_test.go +216 -0
- package/dist/templates/_gateway/cgi.go +133 -0
- package/dist/templates/_gateway/cgi_test.go +156 -0
- package/dist/templates/_gateway/csrf.go +73 -0
- package/dist/templates/_gateway/csrf_test.go +155 -0
- package/dist/templates/_gateway/directory.go +108 -0
- package/dist/templates/_gateway/directory_test.go +202 -0
- package/dist/templates/_gateway/gateway.go +412 -0
- package/dist/templates/_gateway/gateway_test.go +676 -0
- package/dist/templates/_gateway/go.mod +3 -0
- package/dist/templates/_gateway/groups.go +66 -0
- package/dist/templates/_gateway/main.go +45 -0
- package/dist/templates/binary/synology-app.yaml +1 -1
- package/dist/templates/compose-import/compose.yaml +1 -1
- package/dist/templates/compose-import/synology-app.yaml +1 -1
- package/dist/templates/hello-files/compose.yaml +1 -1
- package/dist/templates/hello-files/synology-app.yaml +1 -1
- package/dist/templates/hello-web/compose.yaml +5 -2
- package/dist/templates/hello-web/synology-app.yaml +4 -1
- package/dist/templates/hello-web-page/compose.yaml +5 -2
- package/dist/templates/hello-web-page/synology-app.yaml +4 -1
- package/dist/templates/native-go/README.md +93 -4
- package/dist/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +3 -1
- package/dist/templates/native-go/backend/cmd/app/main.go +17 -0
- package/dist/templates/native-go/backend/cmd/app/sdk_main.go +60 -0
- package/dist/templates/native-go/backend/cmd/background-worker/main.go +38 -0
- package/dist/templates/native-go/backend/cmd/helper/main.go +10 -1
- package/dist/templates/native-go/backend/cmd/helper/sdk_registry.go +19 -0
- package/dist/templates/native-go/backend/go.mod +5 -3
- package/dist/templates/native-go/backend/go.sum +4 -4
- package/dist/templates/native-go/backend/internal/api/registry.go +17 -6
- package/dist/templates/native-go/backend/internal/api/server.go +7 -1
- package/dist/templates/native-go/backend/internal/app/background.go +270 -0
- package/dist/templates/native-go/backend/internal/app/background_none.go +8 -0
- package/dist/templates/native-go/backend/internal/app/background_owner.go +59 -0
- package/dist/templates/native-go/backend/internal/app/background_owner_test.go +145 -0
- package/dist/templates/native-go/backend/internal/app/background_schedule.go +74 -0
- package/dist/templates/native-go/backend/internal/app/background_schedule_test.go +62 -0
- package/dist/templates/native-go/backend/internal/app/background_test.go +346 -0
- package/dist/templates/native-go/backend/internal/app/integration_state.go +16 -0
- package/dist/templates/native-go/backend/internal/app/migrations.go +41 -0
- package/dist/templates/native-go/backend/internal/app/migrations_test.go +41 -0
- package/dist/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +8 -0
- package/dist/templates/native-go/backend/internal/app/routes.go +17 -3
- package/dist/templates/native-go/backend/internal/app/routes_test.go +20 -3
- package/dist/templates/native-go/backend/internal/app/sdk_jobs.go +70 -0
- package/dist/templates/native-go/backend/internal/app/sdk_jobs_test.go +116 -0
- package/dist/templates/native-go/backend/internal/app/sdk_routes.go +174 -0
- package/dist/templates/native-go/backend/internal/app/session_files.go +15 -0
- package/dist/templates/native-go/backend/internal/app/session_files_test.go +26 -0
- package/dist/templates/native-go/backend/internal/app/shared_folder.go +144 -0
- package/dist/templates/native-go/backend/internal/app/shared_folder_test.go +158 -0
- package/dist/templates/native-go/backend/internal/background/access.go +57 -0
- package/dist/templates/native-go/backend/internal/background/owner_test.go +126 -0
- package/dist/templates/native-go/backend/internal/background/runner.go +185 -0
- package/dist/templates/native-go/backend/internal/background/runner_test.go +209 -0
- package/dist/templates/native-go/backend/internal/background/schedule.go +300 -0
- package/dist/templates/native-go/backend/internal/background/schedule_test.go +335 -0
- package/dist/templates/native-go/backend/internal/background/store.go +807 -0
- package/dist/templates/native-go/backend/internal/background/store_test.go +407 -0
- package/dist/templates/native-go/backend/internal/datamigrate/migrate.go +191 -0
- package/dist/templates/native-go/backend/internal/datamigrate/migrate_test.go +177 -0
- package/dist/templates/native-go/backend/internal/filestation/browse_test.go +67 -0
- package/dist/templates/native-go/backend/internal/filestation/client.go +251 -0
- package/dist/templates/native-go/backend/internal/filestation/client_test.go +155 -0
- package/dist/templates/native-go/backend/internal/filestation/doc.go +4 -0
- package/dist/templates/native-go/backend/internal/filestation/read_file_test.go +90 -0
- package/dist/templates/native-go/backend/internal/filestation/repository.go +207 -0
- package/dist/templates/native-go/backend/internal/filestation/repository_test.go +104 -0
- package/dist/templates/native-go/backend/internal/filestation/sdk_session.go +241 -0
- package/dist/templates/native-go/backend/internal/filestation/sdk_session_test.go +183 -0
- package/dist/templates/native-go/backend/internal/filestation/service.go +254 -0
- package/dist/templates/native-go/backend/internal/filestation/service_test.go +94 -0
- package/dist/templates/native-go/backend/internal/filestation/session_semantics_test.go +383 -0
- package/dist/templates/native-go/backend/internal/filestation/write.go +72 -0
- package/dist/templates/native-go/backend/internal/filestation/write_test.go +123 -0
- package/dist/templates/native-go/backend/internal/helper/background_proof.go +163 -0
- package/dist/templates/native-go/backend/internal/helper/background_proof_contract.go +46 -0
- package/dist/templates/native-go/backend/internal/helper/background_proof_test.go +161 -0
- package/dist/templates/native-go/backend/internal/helper/data_contract.go +3 -0
- package/dist/templates/native-go/backend/internal/helper/data_protocol.go +3 -0
- package/dist/templates/native-go/backend/internal/helper/data_protocol_test.go +1 -1
- package/dist/templates/native-go/backend/internal/helper/grant_authority.go +3 -0
- package/dist/templates/native-go/backend/internal/helper/grant_authority_test.go +1 -1
- package/dist/templates/native-go/backend/internal/helper/grant_repository_linux.go +2 -1
- package/dist/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +4 -3
- package/dist/templates/native-go/backend/internal/helper/grant_snapshot.go +3 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/bindings.go +48 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/contract_test.go +436 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/decode.go +185 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/digest.go +55 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/registry.go +85 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/registry_test.go +73 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/result.go +53 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/stub.go +8 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/testdata/input-digests.json +127 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/types.go +234 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/types_test.go +29 -0
- package/dist/templates/native-go/backend/internal/helper/jobcontract/validate.go +462 -0
- package/dist/templates/native-go/backend/internal/helper/legacy_authority_schema_linux_test.go +34 -0
- package/dist/templates/native-go/backend/internal/helper/legacy_authority_schema_test.go +6 -0
- package/dist/templates/native-go/backend/internal/helper/management.go +79 -0
- package/dist/templates/native-go/backend/internal/helper/observation.go +42 -2
- package/dist/templates/native-go/backend/internal/helper/observation_health_test.go +13 -1
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic.go +56 -10
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +6 -0
- package/dist/templates/native-go/backend/internal/helper/observer_diagnostic_writer.go +40 -0
- package/dist/templates/native-go/backend/internal/helper/process_linux.go +3 -0
- package/dist/templates/native-go/backend/internal/helper/query_deadline_linux_test.go +115 -0
- package/dist/templates/native-go/backend/internal/helper/query_pending_diagnostic_test.go +254 -0
- package/dist/templates/native-go/backend/internal/helper/relaxed_invalidation.go +3 -0
- package/dist/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +23 -4
- package/dist/templates/native-go/backend/internal/helper/sdk_assembly_linux.go +51 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_attach.go +83 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_attach_contract.go +32 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_attach_test.go +184 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_authority_schema_test.go +6 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_background_authority.go +832 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_background_authority_test.go +714 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_background_invalidation.go +218 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_background_lease.go +218 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_background_snapshot.go +110 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_background_store_linux_test.go +261 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_background_store_test.go +58 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_bindings.go +60 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_data_contract.go +251 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_data_protocol.go +424 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_dispatch_absence_test.go +51 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_display.go +488 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_display_contract.go +121 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_display_test.go +459 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_grant_authority.go +559 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_grant_repository_linux.go +417 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_grant_snapshot.go +94 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_history.go +80 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_history_test.go +76 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_job.go +697 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_job_child_linux.go +309 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_job_contract.go +122 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_job_linux_test.go +159 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_job_process_linux.go +327 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_job_test.go +501 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_job_vm_linux_test.go +343 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_journal.go +77 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_journal_linux.go +244 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_journal_linux_test.go +295 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_journal_test.go +71 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_picker_test.go +50 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_process_linux.go +184 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_public_vm_linux_test.go +129 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_relaxed_invalidation.go +242 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_rpc.go +299 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_rpc_contract.go +70 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_rpc_test.go +135 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_server_linux.go +152 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_session.go +677 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_session_contract.go +72 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_session_fence_test.go +215 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_session_test.go +475 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_supervisor_frame.go +78 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_supervisor_linux.go +414 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_transport.go +79 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_transport_linux.go +82 -0
- package/dist/templates/native-go/backend/internal/helper/sdk_transport_test.go +64 -0
- package/dist/templates/native-go/backend/internal/helper/server_linux.go +3 -0
- package/dist/templates/native-go/backend/internal/helper/stale_management_linux_test.go +126 -0
- package/dist/templates/native-go/backend/internal/helper/stale_management_test.go +122 -0
- package/dist/templates/native-go/backend/internal/helper/startup_diagnostic.go +68 -0
- package/dist/templates/native-go/backend/internal/helper/startup_diagnostic_linux_test.go +126 -0
- package/dist/templates/native-go/backend/internal/helper/startup_diagnostic_test.go +117 -0
- package/dist/templates/native-go/backend/internal/helper/status.go +22 -13
- package/dist/templates/native-go/backend/internal/helper/status_test.go +45 -0
- package/dist/templates/native-go/backend/internal/helper/supervision.go +1 -1
- package/dist/templates/native-go/backend/internal/helper/supervisor_frame.go +3 -0
- package/dist/templates/native-go/backend/internal/helper/supervisor_linux.go +6 -2
- package/dist/templates/native-go/backend/internal/helper/unit_connection_test.go +22 -4
- package/dist/templates/native-go/backend/internal/helper/unit_linux.go +7 -3
- package/dist/templates/native-go/backend/internal/helper/unit_query_linux.go +5 -1
- package/dist/templates/native-go/backend/internal/helper/write_files_linux.go +7 -4
- package/dist/templates/native-go/backend/internal/helper/write_files_linux_test.go +26 -0
- package/dist/templates/native-go/dsm-package.yaml +1 -1
- package/dist/templates/native-go-background/BACKGROUND.md +111 -0
- package/dist/templates/native-go-background/backend/internal/app/background_on.go +7 -0
- package/dist/templates/native-go-background/backend/internal/app/background_routes_test.go +32 -0
- package/dist/templates/native-go-background/frontend/src/background/BackgroundPanel.vue +178 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n/de.json +83 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n/en.json +83 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n/es.json +83 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n/fr.json +83 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n/it.json +83 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n/ja.json +83 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n/ko.json +83 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n/zh-CN.json +83 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n/zh-TW.json +83 -0
- package/dist/templates/native-go-background/frontend/src/background/i18n.ts +19 -0
- package/dist/templates/native-go-background/frontend/src/background/picker-provider.ts +13 -0
- package/dist/templates/native-go-background/frontend/test/background.test.ts +179 -0
- package/dist/templates/native-go-integration/backend/internal/app/personal.go +2 -2
- package/dist/templates/native-go-integration/backend/internal/app/personal_test.go +37 -0
- package/dist/templates/native-go-vue/README.md +38 -7
- package/dist/templates/native-go-vue/frontend/DESIGN.md +15 -3
- package/dist/templates/native-go-vue/frontend/README-JOBS.md +75 -0
- package/dist/templates/native-go-vue/frontend/README-M2.md +64 -0
- package/dist/templates/native-go-vue/frontend/package-lock.json +5 -4
- package/dist/templates/native-go-vue/frontend/package.json +1 -1
- package/dist/templates/native-go-vue/frontend/src/App.vue +39 -11
- package/dist/templates/native-go-vue/frontend/src/M2App.vue +57 -0
- package/dist/templates/native-go-vue/frontend/src/SDKApp.vue +203 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/InteractiveJobForm.vue +70 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/JobsAdminPanel.vue +33 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/JobsPanel.vue +135 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/connected-provider.ts +179 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n/de.json +62 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n/en.json +62 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n/es.json +62 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n/fr.json +62 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n/it.json +62 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n/ja.json +62 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n/ko.json +62 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n/zh-CN.json +62 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n/zh-TW.json +62 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/i18n.ts +15 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/mock-provider.ts +67 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/provider.ts +60 -0
- package/dist/templates/native-go-vue/frontend/src/jobs/validate.ts +44 -0
- package/dist/templates/native-go-vue/frontend/src/m2-main.ts +21 -0
- package/dist/templates/native-go-vue/frontend/src/m2-style.css +7 -0
- package/dist/templates/native-go-vue/frontend/src/nas/M2Files.vue +94 -0
- package/dist/templates/native-go-vue/frontend/src/nas/M2PathPicker.vue +70 -0
- package/dist/templates/native-go-vue/frontend/src/nas/M2Settings.vue +69 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/de.json +56 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/en.json +56 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/es.json +56 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/fr.json +56 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/it.json +56 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/ja.json +56 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/ko.json +56 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/zh-CN.json +56 -0
- package/dist/templates/native-go-vue/frontend/src/nas/i18n/m2/zh-TW.json +56 -0
- package/dist/templates/native-go-vue/frontend/src/nas/m2-contract.ts +33 -0
- package/dist/templates/native-go-vue/frontend/src/nas/m2-i18n.ts +24 -0
- package/dist/templates/native-go-vue/frontend/src/nas/m2-provider.ts +104 -0
- package/dist/templates/native-go-vue/frontend/src/nas/use-m2-request.ts +18 -0
- package/dist/templates/native-go-vue/frontend/src/sdk-main.ts +39 -0
- package/dist/templates/native-go-vue/frontend/src/shell/AppShell.vue +48 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/de.json +10 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/en.json +10 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/es.json +10 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/fr.json +10 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/it.json +10 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/ja.json +10 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/ko.json +10 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/zh-CN.json +10 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n/zh-TW.json +10 -0
- package/dist/templates/native-go-vue/frontend/src/shell/i18n.ts +17 -0
- package/dist/templates/native-go-vue/frontend/src/shell/pages.ts +34 -0
- package/dist/templates/native-go-vue/frontend/src/style.css +2 -6
- package/dist/templates/native-go-vue/frontend/test/apps.test.ts +21 -0
- package/dist/templates/native-go-vue/frontend/test/jobs-connected.test.ts +163 -0
- package/dist/templates/native-go-vue/frontend/test/jobs-preview.html +22 -0
- package/dist/templates/native-go-vue/frontend/test/jobs.test.ts +176 -0
- package/dist/templates/native-go-vue/frontend/test/m2-preview.html +27 -0
- package/dist/templates/native-go-vue/frontend/test/m2-provider.test.ts +87 -0
- package/dist/templates/native-go-vue/frontend/test/m2-ui.test.ts +209 -0
- package/dist/templates/native-go-vue/frontend/test/native-controls.test.ts +27 -0
- package/dist/templates/native-go-vue/frontend/test/picker-wire.test.ts +110 -0
- package/dist/templates/native-go-vue/frontend/test/shell-preview.html +19 -0
- package/dist/templates/native-go-vue/frontend/test/shell-sdk.test.ts +73 -0
- package/dist/templates/native-go-vue/frontend/test/shell-ui.test.ts +114 -0
- package/dist/templates/native-go-vue/frontend/test/shell.test.ts +45 -0
- package/dist/templates/native-go-vue/frontend/vite.config.ts +2 -2
- package/dist/validate.js +6 -3
- package/package.json +1 -1
- package/schema/synology-app.schema.json +19 -0
- package/skills/reference/create.md +4 -0
- package/templates/_daemon/go.mod +2 -0
- package/templates/_gateway/auth.go +101 -0
- package/templates/_gateway/auth_test.go +216 -0
- package/templates/_gateway/cgi.go +133 -0
- package/templates/_gateway/cgi_test.go +156 -0
- package/templates/_gateway/csrf.go +73 -0
- package/templates/_gateway/csrf_test.go +155 -0
- package/templates/_gateway/directory.go +108 -0
- package/templates/_gateway/directory_test.go +202 -0
- package/templates/_gateway/gateway.go +412 -0
- package/templates/_gateway/gateway_test.go +676 -0
- package/templates/_gateway/go.mod +3 -0
- package/templates/_gateway/groups.go +66 -0
- package/templates/_gateway/main.go +45 -0
- package/templates/binary/synology-app.yaml +1 -1
- package/templates/compose-import/compose.yaml +1 -1
- package/templates/compose-import/synology-app.yaml +1 -1
- package/templates/hello-files/compose.yaml +1 -1
- package/templates/hello-files/synology-app.yaml +1 -1
- package/templates/hello-web/compose.yaml +5 -2
- package/templates/hello-web/synology-app.yaml +4 -1
- package/templates/hello-web-page/compose.yaml +5 -2
- package/templates/hello-web-page/synology-app.yaml +4 -1
- package/templates/native-go/README.md +93 -4
- package/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +3 -1
- package/templates/native-go/backend/cmd/app/main.go +17 -0
- package/templates/native-go/backend/cmd/app/sdk_main.go +60 -0
- package/templates/native-go/backend/cmd/background-worker/main.go +38 -0
- package/templates/native-go/backend/cmd/helper/main.go +10 -1
- package/templates/native-go/backend/cmd/helper/sdk_registry.go +19 -0
- package/templates/native-go/backend/go.mod +5 -3
- package/templates/native-go/backend/go.sum +4 -4
- package/templates/native-go/backend/internal/api/registry.go +17 -6
- package/templates/native-go/backend/internal/api/server.go +7 -1
- package/templates/native-go/backend/internal/app/background.go +270 -0
- package/templates/native-go/backend/internal/app/background_none.go +8 -0
- package/templates/native-go/backend/internal/app/background_owner.go +59 -0
- package/templates/native-go/backend/internal/app/background_owner_test.go +145 -0
- package/templates/native-go/backend/internal/app/background_schedule.go +74 -0
- package/templates/native-go/backend/internal/app/background_schedule_test.go +62 -0
- package/templates/native-go/backend/internal/app/background_test.go +346 -0
- package/templates/native-go/backend/internal/app/integration_state.go +16 -0
- package/templates/native-go/backend/internal/app/migrations.go +41 -0
- package/templates/native-go/backend/internal/app/migrations_test.go +41 -0
- package/templates/native-go/backend/internal/app/nas_cgi_artifact_test.go +8 -0
- package/templates/native-go/backend/internal/app/routes.go +17 -3
- package/templates/native-go/backend/internal/app/routes_test.go +20 -3
- package/templates/native-go/backend/internal/app/sdk_jobs.go +70 -0
- package/templates/native-go/backend/internal/app/sdk_jobs_test.go +116 -0
- package/templates/native-go/backend/internal/app/sdk_routes.go +174 -0
- package/templates/native-go/backend/internal/app/session_files.go +15 -0
- package/templates/native-go/backend/internal/app/session_files_test.go +26 -0
- package/templates/native-go/backend/internal/app/shared_folder.go +144 -0
- package/templates/native-go/backend/internal/app/shared_folder_test.go +158 -0
- package/templates/native-go/backend/internal/background/access.go +57 -0
- package/templates/native-go/backend/internal/background/owner_test.go +126 -0
- package/templates/native-go/backend/internal/background/runner.go +185 -0
- package/templates/native-go/backend/internal/background/runner_test.go +209 -0
- package/templates/native-go/backend/internal/background/schedule.go +300 -0
- package/templates/native-go/backend/internal/background/schedule_test.go +335 -0
- package/templates/native-go/backend/internal/background/store.go +807 -0
- package/templates/native-go/backend/internal/background/store_test.go +407 -0
- package/templates/native-go/backend/internal/datamigrate/migrate.go +191 -0
- package/templates/native-go/backend/internal/datamigrate/migrate_test.go +177 -0
- package/templates/native-go/backend/internal/filestation/browse_test.go +67 -0
- package/templates/native-go/backend/internal/filestation/client.go +251 -0
- package/templates/native-go/backend/internal/filestation/client_test.go +155 -0
- package/templates/native-go/backend/internal/filestation/doc.go +4 -0
- package/templates/native-go/backend/internal/filestation/read_file_test.go +90 -0
- package/templates/native-go/backend/internal/filestation/repository.go +207 -0
- package/templates/native-go/backend/internal/filestation/repository_test.go +104 -0
- package/templates/native-go/backend/internal/filestation/sdk_session.go +241 -0
- package/templates/native-go/backend/internal/filestation/sdk_session_test.go +183 -0
- package/templates/native-go/backend/internal/filestation/service.go +254 -0
- package/templates/native-go/backend/internal/filestation/service_test.go +94 -0
- package/templates/native-go/backend/internal/filestation/session_semantics_test.go +383 -0
- package/templates/native-go/backend/internal/filestation/write.go +72 -0
- package/templates/native-go/backend/internal/filestation/write_test.go +123 -0
- package/templates/native-go/backend/internal/helper/background_proof.go +163 -0
- package/templates/native-go/backend/internal/helper/background_proof_contract.go +46 -0
- package/templates/native-go/backend/internal/helper/background_proof_test.go +161 -0
- package/templates/native-go/backend/internal/helper/data_contract.go +3 -0
- package/templates/native-go/backend/internal/helper/data_protocol.go +3 -0
- package/templates/native-go/backend/internal/helper/data_protocol_test.go +1 -1
- package/templates/native-go/backend/internal/helper/grant_authority.go +3 -0
- package/templates/native-go/backend/internal/helper/grant_authority_test.go +1 -1
- package/templates/native-go/backend/internal/helper/grant_repository_linux.go +2 -1
- package/templates/native-go/backend/internal/helper/grant_repository_linux_test.go +4 -3
- package/templates/native-go/backend/internal/helper/grant_snapshot.go +3 -0
- package/templates/native-go/backend/internal/helper/jobcontract/bindings.go +48 -0
- package/templates/native-go/backend/internal/helper/jobcontract/contract_test.go +436 -0
- package/templates/native-go/backend/internal/helper/jobcontract/decode.go +185 -0
- package/templates/native-go/backend/internal/helper/jobcontract/digest.go +55 -0
- package/templates/native-go/backend/internal/helper/jobcontract/registry.go +85 -0
- package/templates/native-go/backend/internal/helper/jobcontract/registry_test.go +73 -0
- package/templates/native-go/backend/internal/helper/jobcontract/result.go +53 -0
- package/templates/native-go/backend/internal/helper/jobcontract/stub.go +8 -0
- package/templates/native-go/backend/internal/helper/jobcontract/testdata/input-digests.json +127 -0
- package/templates/native-go/backend/internal/helper/jobcontract/types.go +234 -0
- package/templates/native-go/backend/internal/helper/jobcontract/types_test.go +29 -0
- package/templates/native-go/backend/internal/helper/jobcontract/validate.go +462 -0
- package/templates/native-go/backend/internal/helper/legacy_authority_schema_linux_test.go +34 -0
- package/templates/native-go/backend/internal/helper/legacy_authority_schema_test.go +6 -0
- package/templates/native-go/backend/internal/helper/management.go +79 -0
- package/templates/native-go/backend/internal/helper/observation.go +42 -2
- package/templates/native-go/backend/internal/helper/observation_health_test.go +13 -1
- package/templates/native-go/backend/internal/helper/observer_diagnostic.go +56 -10
- package/templates/native-go/backend/internal/helper/observer_diagnostic_linux_test.go +6 -0
- package/templates/native-go/backend/internal/helper/observer_diagnostic_writer.go +40 -0
- package/templates/native-go/backend/internal/helper/process_linux.go +3 -0
- package/templates/native-go/backend/internal/helper/query_deadline_linux_test.go +115 -0
- package/templates/native-go/backend/internal/helper/query_pending_diagnostic_test.go +254 -0
- package/templates/native-go/backend/internal/helper/relaxed_invalidation.go +3 -0
- package/templates/native-go/backend/internal/helper/s1r_actor_races_linux_test.go +23 -4
- package/templates/native-go/backend/internal/helper/sdk_assembly_linux.go +51 -0
- package/templates/native-go/backend/internal/helper/sdk_attach.go +83 -0
- package/templates/native-go/backend/internal/helper/sdk_attach_contract.go +32 -0
- package/templates/native-go/backend/internal/helper/sdk_attach_test.go +184 -0
- package/templates/native-go/backend/internal/helper/sdk_authority_schema_test.go +6 -0
- package/templates/native-go/backend/internal/helper/sdk_background_authority.go +832 -0
- package/templates/native-go/backend/internal/helper/sdk_background_authority_test.go +714 -0
- package/templates/native-go/backend/internal/helper/sdk_background_invalidation.go +218 -0
- package/templates/native-go/backend/internal/helper/sdk_background_lease.go +218 -0
- package/templates/native-go/backend/internal/helper/sdk_background_snapshot.go +110 -0
- package/templates/native-go/backend/internal/helper/sdk_background_store_linux_test.go +261 -0
- package/templates/native-go/backend/internal/helper/sdk_background_store_test.go +58 -0
- package/templates/native-go/backend/internal/helper/sdk_bindings.go +60 -0
- package/templates/native-go/backend/internal/helper/sdk_data_contract.go +251 -0
- package/templates/native-go/backend/internal/helper/sdk_data_protocol.go +424 -0
- package/templates/native-go/backend/internal/helper/sdk_dispatch_absence_test.go +51 -0
- package/templates/native-go/backend/internal/helper/sdk_display.go +488 -0
- package/templates/native-go/backend/internal/helper/sdk_display_contract.go +121 -0
- package/templates/native-go/backend/internal/helper/sdk_display_test.go +459 -0
- package/templates/native-go/backend/internal/helper/sdk_grant_authority.go +559 -0
- package/templates/native-go/backend/internal/helper/sdk_grant_repository_linux.go +417 -0
- package/templates/native-go/backend/internal/helper/sdk_grant_snapshot.go +94 -0
- package/templates/native-go/backend/internal/helper/sdk_history.go +80 -0
- package/templates/native-go/backend/internal/helper/sdk_history_test.go +76 -0
- package/templates/native-go/backend/internal/helper/sdk_job.go +697 -0
- package/templates/native-go/backend/internal/helper/sdk_job_child_linux.go +309 -0
- package/templates/native-go/backend/internal/helper/sdk_job_contract.go +122 -0
- package/templates/native-go/backend/internal/helper/sdk_job_linux_test.go +159 -0
- package/templates/native-go/backend/internal/helper/sdk_job_process_linux.go +327 -0
- package/templates/native-go/backend/internal/helper/sdk_job_test.go +501 -0
- package/templates/native-go/backend/internal/helper/sdk_job_vm_linux_test.go +343 -0
- package/templates/native-go/backend/internal/helper/sdk_journal.go +77 -0
- package/templates/native-go/backend/internal/helper/sdk_journal_linux.go +244 -0
- package/templates/native-go/backend/internal/helper/sdk_journal_linux_test.go +295 -0
- package/templates/native-go/backend/internal/helper/sdk_journal_test.go +71 -0
- package/templates/native-go/backend/internal/helper/sdk_picker_test.go +50 -0
- package/templates/native-go/backend/internal/helper/sdk_process_linux.go +184 -0
- package/templates/native-go/backend/internal/helper/sdk_public_vm_linux_test.go +129 -0
- package/templates/native-go/backend/internal/helper/sdk_relaxed_invalidation.go +242 -0
- package/templates/native-go/backend/internal/helper/sdk_rpc.go +299 -0
- package/templates/native-go/backend/internal/helper/sdk_rpc_contract.go +70 -0
- package/templates/native-go/backend/internal/helper/sdk_rpc_test.go +135 -0
- package/templates/native-go/backend/internal/helper/sdk_server_linux.go +152 -0
- package/templates/native-go/backend/internal/helper/sdk_session.go +677 -0
- package/templates/native-go/backend/internal/helper/sdk_session_contract.go +72 -0
- package/templates/native-go/backend/internal/helper/sdk_session_fence_test.go +215 -0
- package/templates/native-go/backend/internal/helper/sdk_session_test.go +475 -0
- package/templates/native-go/backend/internal/helper/sdk_supervisor_frame.go +78 -0
- package/templates/native-go/backend/internal/helper/sdk_supervisor_linux.go +414 -0
- package/templates/native-go/backend/internal/helper/sdk_transport.go +79 -0
- package/templates/native-go/backend/internal/helper/sdk_transport_linux.go +82 -0
- package/templates/native-go/backend/internal/helper/sdk_transport_test.go +64 -0
- package/templates/native-go/backend/internal/helper/server_linux.go +3 -0
- package/templates/native-go/backend/internal/helper/stale_management_linux_test.go +126 -0
- package/templates/native-go/backend/internal/helper/stale_management_test.go +122 -0
- package/templates/native-go/backend/internal/helper/startup_diagnostic.go +68 -0
- package/templates/native-go/backend/internal/helper/startup_diagnostic_linux_test.go +126 -0
- package/templates/native-go/backend/internal/helper/startup_diagnostic_test.go +117 -0
- package/templates/native-go/backend/internal/helper/status.go +22 -13
- package/templates/native-go/backend/internal/helper/status_test.go +45 -0
- package/templates/native-go/backend/internal/helper/supervision.go +1 -1
- package/templates/native-go/backend/internal/helper/supervisor_frame.go +3 -0
- package/templates/native-go/backend/internal/helper/supervisor_linux.go +6 -2
- package/templates/native-go/backend/internal/helper/unit_connection_test.go +22 -4
- package/templates/native-go/backend/internal/helper/unit_linux.go +7 -3
- package/templates/native-go/backend/internal/helper/unit_query_linux.go +5 -1
- package/templates/native-go/backend/internal/helper/write_files_linux.go +7 -4
- package/templates/native-go/backend/internal/helper/write_files_linux_test.go +26 -0
- package/templates/native-go/dsm-package.yaml +1 -1
- package/templates/native-go-background/BACKGROUND.md +111 -0
- package/templates/native-go-background/backend/internal/app/background_on.go +7 -0
- package/templates/native-go-background/backend/internal/app/background_routes_test.go +32 -0
- package/templates/native-go-background/frontend/src/background/BackgroundPanel.vue +178 -0
- package/templates/native-go-background/frontend/src/background/i18n/de.json +83 -0
- package/templates/native-go-background/frontend/src/background/i18n/en.json +83 -0
- package/templates/native-go-background/frontend/src/background/i18n/es.json +83 -0
- package/templates/native-go-background/frontend/src/background/i18n/fr.json +83 -0
- package/templates/native-go-background/frontend/src/background/i18n/it.json +83 -0
- package/templates/native-go-background/frontend/src/background/i18n/ja.json +83 -0
- package/templates/native-go-background/frontend/src/background/i18n/ko.json +83 -0
- package/templates/native-go-background/frontend/src/background/i18n/zh-CN.json +83 -0
- package/templates/native-go-background/frontend/src/background/i18n/zh-TW.json +83 -0
- package/templates/native-go-background/frontend/src/background/i18n.ts +19 -0
- package/templates/native-go-background/frontend/src/background/picker-provider.ts +13 -0
- package/templates/native-go-background/frontend/test/background.test.ts +179 -0
- package/templates/native-go-integration/backend/internal/app/personal.go +2 -2
- package/templates/native-go-integration/backend/internal/app/personal_test.go +37 -0
- package/templates/native-go-vue/README.md +38 -7
- package/templates/native-go-vue/frontend/DESIGN.md +15 -3
- package/templates/native-go-vue/frontend/README-JOBS.md +75 -0
- package/templates/native-go-vue/frontend/README-M2.md +64 -0
- package/templates/native-go-vue/frontend/package-lock.json +5 -4
- package/templates/native-go-vue/frontend/package.json +1 -1
- package/templates/native-go-vue/frontend/src/App.vue +39 -11
- package/templates/native-go-vue/frontend/src/M2App.vue +57 -0
- package/templates/native-go-vue/frontend/src/SDKApp.vue +203 -0
- package/templates/native-go-vue/frontend/src/jobs/InteractiveJobForm.vue +70 -0
- package/templates/native-go-vue/frontend/src/jobs/JobsAdminPanel.vue +33 -0
- package/templates/native-go-vue/frontend/src/jobs/JobsPanel.vue +135 -0
- package/templates/native-go-vue/frontend/src/jobs/connected-provider.ts +179 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n/de.json +62 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n/en.json +62 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n/es.json +62 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n/fr.json +62 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n/it.json +62 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n/ja.json +62 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n/ko.json +62 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n/zh-CN.json +62 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n/zh-TW.json +62 -0
- package/templates/native-go-vue/frontend/src/jobs/i18n.ts +15 -0
- package/templates/native-go-vue/frontend/src/jobs/mock-provider.ts +67 -0
- package/templates/native-go-vue/frontend/src/jobs/provider.ts +60 -0
- package/templates/native-go-vue/frontend/src/jobs/validate.ts +44 -0
- package/templates/native-go-vue/frontend/src/m2-main.ts +21 -0
- package/templates/native-go-vue/frontend/src/m2-style.css +7 -0
- package/templates/native-go-vue/frontend/src/nas/M2Files.vue +94 -0
- package/templates/native-go-vue/frontend/src/nas/M2PathPicker.vue +70 -0
- package/templates/native-go-vue/frontend/src/nas/M2Settings.vue +69 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/m2/de.json +56 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/m2/en.json +56 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/m2/es.json +56 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/m2/fr.json +56 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/m2/it.json +56 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/m2/ja.json +56 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/m2/ko.json +56 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/m2/zh-CN.json +56 -0
- package/templates/native-go-vue/frontend/src/nas/i18n/m2/zh-TW.json +56 -0
- package/templates/native-go-vue/frontend/src/nas/m2-contract.ts +33 -0
- package/templates/native-go-vue/frontend/src/nas/m2-i18n.ts +24 -0
- package/templates/native-go-vue/frontend/src/nas/m2-provider.ts +104 -0
- package/templates/native-go-vue/frontend/src/nas/use-m2-request.ts +18 -0
- package/templates/native-go-vue/frontend/src/sdk-main.ts +39 -0
- package/templates/native-go-vue/frontend/src/shell/AppShell.vue +48 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/de.json +10 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/en.json +10 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/es.json +10 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/fr.json +10 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/it.json +10 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/ja.json +10 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/ko.json +10 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/zh-CN.json +10 -0
- package/templates/native-go-vue/frontend/src/shell/i18n/zh-TW.json +10 -0
- package/templates/native-go-vue/frontend/src/shell/i18n.ts +17 -0
- package/templates/native-go-vue/frontend/src/shell/pages.ts +34 -0
- package/templates/native-go-vue/frontend/src/style.css +2 -6
- package/templates/native-go-vue/frontend/test/apps.test.ts +21 -0
- package/templates/native-go-vue/frontend/test/jobs-connected.test.ts +163 -0
- package/templates/native-go-vue/frontend/test/jobs-preview.html +22 -0
- package/templates/native-go-vue/frontend/test/jobs.test.ts +176 -0
- package/templates/native-go-vue/frontend/test/m2-preview.html +27 -0
- package/templates/native-go-vue/frontend/test/m2-provider.test.ts +87 -0
- package/templates/native-go-vue/frontend/test/m2-ui.test.ts +209 -0
- package/templates/native-go-vue/frontend/test/native-controls.test.ts +27 -0
- package/templates/native-go-vue/frontend/test/picker-wire.test.ts +110 -0
- package/templates/native-go-vue/frontend/test/shell-preview.html +19 -0
- package/templates/native-go-vue/frontend/test/shell-sdk.test.ts +73 -0
- package/templates/native-go-vue/frontend/test/shell-ui.test.ts +114 -0
- package/templates/native-go-vue/frontend/test/shell.test.ts +45 -0
- package/templates/native-go-vue/frontend/vite.config.ts +2 -2
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
package jobcontract
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"bytes"
|
|
5
|
+
"crypto/sha256"
|
|
6
|
+
"encoding/hex"
|
|
7
|
+
"encoding/json"
|
|
8
|
+
"os"
|
|
9
|
+
"strings"
|
|
10
|
+
"testing"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
func opaque(id string) string { h := sha256.Sum256([]byte(id)); return hex.EncodeToString(h[:]) }
|
|
14
|
+
func ref(id string) RevisionRef { return RevisionRef{ID: opaque(id), Revision: 1} }
|
|
15
|
+
func digest() string { return strings.Repeat("a", 64) }
|
|
16
|
+
func inputFixture() Input {
|
|
17
|
+
n := uint64(12)
|
|
18
|
+
return Input{Steps: []Step{{Action: Read, Segments: []string{"\u5831\u544a<&\U0001f600"}, MaxBytes: &n}}}
|
|
19
|
+
}
|
|
20
|
+
func bindingFixture() Binding {
|
|
21
|
+
return Binding{Inventory: Inventory{Package: "fixture", Version: "1.0.0-0001", Protocol: 2, PayloadDigest: digest(), RegistryDigest: digest(), DataAccess: "relaxed"}, JobSchema: 1, Epoch: opaque("epoch-1"), Job: ref("job-1"), Worker: ref("worker-1"), ParentGrant: ref("grant-1"), ApprovalBinding: digest(), CapabilityDigest: digest(), InputSchemaDigest: digest(), InputDigest: digest(), Mode: Interactive}
|
|
22
|
+
}
|
|
23
|
+
func controlFixture() Control {
|
|
24
|
+
return Control{Op: "jobs.submit", Binding: bindingFixture(), Intent: ref("intent-1"), Nonce: opaque("nonce-1"), Ticket: opaque("ticket-1")}
|
|
25
|
+
}
|
|
26
|
+
func workerFixture() Worker {
|
|
27
|
+
return Worker{RegistrySchema: 2, ID: "worker-1", Revision: 1, Kind: "sdk-read-plan", HandlerBinding: digest(), InputSchemaDigest: digest(), OutputSchemaDigest: digest(), Actions: []Action{List, Stat, Read, ReadStream}, Modes: []Mode{Interactive, Background}, Checkpoints: []string{"before-step", "before-chunk", "before-result"}, Limits: HardLimits()}
|
|
28
|
+
}
|
|
29
|
+
func wire(t *testing.T, v any) []byte {
|
|
30
|
+
t.Helper()
|
|
31
|
+
b, e := json.Marshal(v)
|
|
32
|
+
if e != nil {
|
|
33
|
+
t.Fatal(e)
|
|
34
|
+
}
|
|
35
|
+
return b
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
func TestStrictInputAndTypedDigest(t *testing.T) {
|
|
39
|
+
raw := []byte(` { "steps" : [{"maxBytes":12,"segments":["\u5831\u544a<&\ud83d\ude00"],"action":"nas.files.read"}] } `)
|
|
40
|
+
in, c := DecodeInput(bytes.NewReader(raw))
|
|
41
|
+
if c != "" {
|
|
42
|
+
t.Fatal(c)
|
|
43
|
+
}
|
|
44
|
+
a, c := InputDigest(in, digest())
|
|
45
|
+
if c != "" {
|
|
46
|
+
t.Fatal(c)
|
|
47
|
+
}
|
|
48
|
+
b, c := InputDigest(inputFixture(), digest())
|
|
49
|
+
if c != "" || a != b {
|
|
50
|
+
t.Fatal("representation changed digest", a, b, c)
|
|
51
|
+
}
|
|
52
|
+
if a != "7e811bf2b8253e47a4b85b596c7b7224fa358470868c0fbe02b4bd05c2bf9b8e" {
|
|
53
|
+
t.Fatal("input v1 golden changed", a)
|
|
54
|
+
}
|
|
55
|
+
for _, raw := range []string{
|
|
56
|
+
`{"steps":[],"extra":1}`, `{"Steps":[]}`, `{"steps":[],"steps":[]}`,
|
|
57
|
+
`{"steps":[],"st\u0065ps":[]}`, `{"steps":null}`, `{"steps":[]} {}`,
|
|
58
|
+
`{"steps":[{"action":"nas.files.stat","segments":[],"segments":[]}]}`,
|
|
59
|
+
`{"steps":[{"action":"nas.files.stat","segments":null}]}`,
|
|
60
|
+
`{"steps":[{"action":"nas.files.stat","segments":["\ud800"]}]}`,
|
|
61
|
+
`{"steps":[{"action":"nas.files.stat","segments":["\udc00"]}]}`,
|
|
62
|
+
`{"steps":[{"action":"nas.files.read","segments":["x"],"maxBytes":null}]}`,
|
|
63
|
+
`{"steps":[{"action":"nas.files.read","segments":["x"],"maxBytes":18446744073709551616}]}`,
|
|
64
|
+
`{"steps":[{"action":"nas.files.read","segments":["x"],"maxBytes":-1}]}`,
|
|
65
|
+
`{"steps":[{"action":"nas.files.read","segments":["x"],"maxBytes":1.5}]}`,
|
|
66
|
+
} {
|
|
67
|
+
if _, c := DecodeInput(strings.NewReader(raw)); c == "" {
|
|
68
|
+
t.Fatalf("accepted invalid input %s", raw)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
invalidUTF8 := append([]byte(`{"steps":[{"action":"nas.files.stat","segments":["`), 0xff)
|
|
72
|
+
invalidUTF8 = append(invalidUTF8, []byte(`"]}]}`)...)
|
|
73
|
+
if _, c := DecodeInput(bytes.NewReader(invalidUTF8)); c != Invalid {
|
|
74
|
+
t.Fatal(c)
|
|
75
|
+
}
|
|
76
|
+
if _, c := DecodeInput(strings.NewReader(strings.Repeat(" ", MaxInputBytes) + string(raw))); c != LimitExceeded {
|
|
77
|
+
t.Fatal(c)
|
|
78
|
+
}
|
|
79
|
+
in.Steps[0].Segments = []string{"\u00e9"}
|
|
80
|
+
x, _ := InputDigest(in, digest())
|
|
81
|
+
in.Steps[0].Segments = []string{"e\u0301"}
|
|
82
|
+
y, _ := InputDigest(in, digest())
|
|
83
|
+
if x == y {
|
|
84
|
+
t.Fatal("Unicode normalized")
|
|
85
|
+
}
|
|
86
|
+
if _, c := InputDigest(in, "bad"); c != Invalid {
|
|
87
|
+
t.Fatal(c)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
func TestSharedInputDigestVectors(t *testing.T) {
|
|
92
|
+
b, err := os.ReadFile("testdata/input-digests.json")
|
|
93
|
+
if err != nil {
|
|
94
|
+
t.Fatal(err)
|
|
95
|
+
}
|
|
96
|
+
var vectors []struct {
|
|
97
|
+
Name string
|
|
98
|
+
Input Input
|
|
99
|
+
SchemaDigest string
|
|
100
|
+
Digest string
|
|
101
|
+
}
|
|
102
|
+
if err := json.Unmarshal(b, &vectors); err != nil {
|
|
103
|
+
t.Fatal(err)
|
|
104
|
+
}
|
|
105
|
+
if len(vectors) != 6 {
|
|
106
|
+
t.Fatal("missing canonical vectors")
|
|
107
|
+
}
|
|
108
|
+
for _, v := range vectors {
|
|
109
|
+
t.Run(v.Name, func(t *testing.T) {
|
|
110
|
+
in, c := DecodeInput(bytes.NewReader(wire(t, v.Input)))
|
|
111
|
+
if c != "" {
|
|
112
|
+
t.Fatal(c)
|
|
113
|
+
}
|
|
114
|
+
got, c := InputDigest(in, v.SchemaDigest)
|
|
115
|
+
if c != "" || got != v.Digest {
|
|
116
|
+
t.Fatal(got, c)
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
func TestEveryRecordUsesStrictDecoder(t *testing.T) {
|
|
123
|
+
b := privateFixture()
|
|
124
|
+
in := inputFixture()
|
|
125
|
+
b.Binding.InputDigest, _ = InputDigest(in, digest())
|
|
126
|
+
i := Intent{JobSchema: 1, ID: opaque("intent-1"), Revision: 1, Binding: b, Input: in, SummaryDigest: digest(), CreatedAt: 1000, ExpiresAt: 31000}
|
|
127
|
+
for _, record := range []struct {
|
|
128
|
+
name string
|
|
129
|
+
value any
|
|
130
|
+
decode func([]byte) SafeReason
|
|
131
|
+
}{
|
|
132
|
+
{"worker", workerFixture(), func(b []byte) SafeReason { _, c := DecodeWorker(bytes.NewReader(b)); return c }},
|
|
133
|
+
{"intent", i, func(b []byte) SafeReason { _, c := DecodeIntent(bytes.NewReader(b)); return c }},
|
|
134
|
+
{"background", backgroundFixture(), func(b []byte) SafeReason { _, c := DecodeBackground(bytes.NewReader(b)); return c }},
|
|
135
|
+
{"job", jobFixture(), func(b []byte) SafeReason { _, c := DecodeJob(bytes.NewReader(b)); return c }},
|
|
136
|
+
} {
|
|
137
|
+
t.Run(record.name, func(t *testing.T) {
|
|
138
|
+
b := wire(t, record.value)
|
|
139
|
+
if c := record.decode(b); c != "" {
|
|
140
|
+
t.Fatal(c)
|
|
141
|
+
}
|
|
142
|
+
for _, raw := range []string{`null`, `{}`, `[]`, string(b) + `{}`, `{"extra":1,` + string(b[1:]), `{"extra":null,` + string(b[1:])} {
|
|
143
|
+
if c := record.decode([]byte(raw)); c != Invalid {
|
|
144
|
+
t.Fatal("invalid record accepted", c)
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if c := record.decode(append(bytes.Repeat([]byte(" "), MaxArtifactBytes), b...)); c != LimitExceeded {
|
|
148
|
+
t.Fatal("unbounded record", c)
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
func TestPlanNarrowsDescriptorAndSafeReasons(t *testing.T) {
|
|
155
|
+
w, in := workerFixture(), inputFixture()
|
|
156
|
+
if c := ValidatePlan(w, in, Background); c != "" {
|
|
157
|
+
t.Fatal(c)
|
|
158
|
+
}
|
|
159
|
+
w.Modes = []Mode{Interactive}
|
|
160
|
+
if c := ValidatePlan(w, in, Background); c != Unsupported {
|
|
161
|
+
t.Fatal(c)
|
|
162
|
+
}
|
|
163
|
+
w = workerFixture()
|
|
164
|
+
w.Actions = []Action{Stat}
|
|
165
|
+
if c := ValidatePlan(w, in, Interactive); c != Unsupported {
|
|
166
|
+
t.Fatal(c)
|
|
167
|
+
}
|
|
168
|
+
w = workerFixture()
|
|
169
|
+
w.Limits.BoundedBytes = 11
|
|
170
|
+
if c := ValidatePlan(w, in, Interactive); c != LimitExceeded {
|
|
171
|
+
t.Fatal(c)
|
|
172
|
+
}
|
|
173
|
+
w = workerFixture()
|
|
174
|
+
w.Limits.InputBytes = 1
|
|
175
|
+
if c := ValidatePlan(w, in, Interactive); c != LimitExceeded {
|
|
176
|
+
t.Fatal(c)
|
|
177
|
+
}
|
|
178
|
+
for _, c := range []SafeReason{Invalid, Incompatible, Unsupported, Replay, Stale, Expired, Denied, Unavailable, Suspended, Revoked, Fenced, Busy, LimitExceeded, ReasonCanceled, Timeout, Partial, CommitUncertain, ReasonCleanupRequired, Internal} {
|
|
179
|
+
if !c.Valid() || c.Error() != string(c) {
|
|
180
|
+
t.Fatal(c)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
for _, c := range []SafeReason{"", "/secret/path", "new-native-error"} {
|
|
184
|
+
if c.Valid() {
|
|
185
|
+
t.Fatal("open safe reason enum", c)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
for _, from := range []State{Succeeded, Failed, Canceled, Interrupted} {
|
|
189
|
+
for _, to := range []State{Pending, Running, CancelRequested, Draining, Succeeded, Failed, Canceled, Interrupted, CleanupRequired} {
|
|
190
|
+
if TransitionAllowed(from, to) {
|
|
191
|
+
t.Fatal("terminal resurrection", from, to)
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
func TestFixedPlanActionsPathsAndWholeJobLimits(t *testing.T) {
|
|
198
|
+
for _, mutate := range []func(*Input){
|
|
199
|
+
func(x *Input) { x.Steps = nil }, func(x *Input) { x.Steps = []Step{} },
|
|
200
|
+
func(x *Input) { x.Steps[0].Action = "nas.files.create" },
|
|
201
|
+
func(x *Input) { x.Steps[0].MaxBytes = nil },
|
|
202
|
+
func(x *Input) { n := uint64(0); x.Steps[0].MaxBytes = &n },
|
|
203
|
+
func(x *Input) { n := uint64(1); x.Steps[0].Limit = &n },
|
|
204
|
+
func(x *Input) { x.Steps[0].Segments = []string{".."} },
|
|
205
|
+
func(x *Input) { x.Steps[0].Segments = []string{"a/b"} },
|
|
206
|
+
func(x *Input) { x.Steps[0].Segments = []string{"a\\b"} },
|
|
207
|
+
func(x *Input) { x.Steps[0].Segments = []string{"\x00"} },
|
|
208
|
+
func(x *Input) { x.Steps[0].Segments = []string{} },
|
|
209
|
+
func(x *Input) { x.Steps = make([]Step, MaxSteps+1) },
|
|
210
|
+
} {
|
|
211
|
+
x := inputFixture()
|
|
212
|
+
mutate(&x)
|
|
213
|
+
if c := ValidateInput(x); c == "" {
|
|
214
|
+
t.Fatal("invalid plan accepted", x)
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
n := uint64(64 << 20)
|
|
218
|
+
x := Input{Steps: []Step{{Action: ReadStream, Segments: []string{"x"}, MaxBytes: &n}}}
|
|
219
|
+
if c := ValidateInput(x); c != "" {
|
|
220
|
+
t.Fatal(c)
|
|
221
|
+
}
|
|
222
|
+
x.Steps = append(x.Steps, x.Steps[0])
|
|
223
|
+
if c := ValidateInput(x); c != LimitExceeded {
|
|
224
|
+
t.Fatal("per-step reset", c)
|
|
225
|
+
}
|
|
226
|
+
x = Input{Steps: []Step{{Action: Stat, Segments: []string{}}}}
|
|
227
|
+
if c := ValidateInput(x); c != "" {
|
|
228
|
+
t.Fatal(c)
|
|
229
|
+
}
|
|
230
|
+
for _, s := range []string{"%2f", "\u5831\u544a\U0001f600"} {
|
|
231
|
+
x.Steps[0].Segments = []string{s}
|
|
232
|
+
if c := ValidateInput(x); c != "" {
|
|
233
|
+
t.Fatal("literal path changed", c)
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
func TestWorkerDescriptorAndLimits(t *testing.T) {
|
|
239
|
+
w := workerFixture()
|
|
240
|
+
if _, c := DecodeWorker(bytes.NewReader(wire(t, w))); c != "" {
|
|
241
|
+
t.Fatal(c)
|
|
242
|
+
}
|
|
243
|
+
for _, mutate := range []func(*Worker){
|
|
244
|
+
func(w *Worker) { w.RegistrySchema = 1 }, func(w *Worker) { w.Kind = "developer-binary" },
|
|
245
|
+
func(w *Worker) { w.Actions = append(w.Actions, w.Actions[0]) },
|
|
246
|
+
func(w *Worker) { w.Modes = append(w.Modes, w.Modes[0]) },
|
|
247
|
+
func(w *Worker) { w.Checkpoints = []string{"before-step"} },
|
|
248
|
+
func(w *Worker) { w.Actions = []Action{"nas.files.publish"} },
|
|
249
|
+
func(w *Worker) { w.Limits.TotalMS++ }, func(w *Worker) { w.Limits.IdleMS = 0 },
|
|
250
|
+
func(w *Worker) { w.Limits.OutstandingLeases = 2 }, func(w *Worker) { w.Revision = MaxSafeInteger + 1 },
|
|
251
|
+
} {
|
|
252
|
+
w := workerFixture()
|
|
253
|
+
mutate(&w)
|
|
254
|
+
if _, c := DecodeWorker(bytes.NewReader(wire(t, w))); c == "" {
|
|
255
|
+
t.Fatal("bad worker accepted", w)
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
w = workerFixture()
|
|
259
|
+
w.Limits.Steps = 1
|
|
260
|
+
if _, c := DecodeWorker(bytes.NewReader(wire(t, w))); c != "" {
|
|
261
|
+
t.Fatal("lower ceiling rejected", c)
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
func TestControlVersionAndModeSeparation(t *testing.T) {
|
|
266
|
+
r := controlFixture()
|
|
267
|
+
if _, c := DecodeControl(bytes.NewReader(wire(t, r))); c != "" {
|
|
268
|
+
t.Fatal(c)
|
|
269
|
+
}
|
|
270
|
+
for _, mutate := range []func(*Control){
|
|
271
|
+
func(r *Control) { r.Binding.Inventory.Protocol = 1 }, func(r *Control) { r.Binding.JobSchema = 0 },
|
|
272
|
+
func(r *Control) { r.Binding.Inventory.DataAccess = "unavailable" }, func(r *Control) { r.Binding.Inventory.DataAccess = "strict" },
|
|
273
|
+
func(r *Control) { r.Binding.Mode = "managed" }, func(r *Control) { d := ref("d"); r.Binding.Delegation = &d },
|
|
274
|
+
func(r *Control) { r.Binding.Mode = Background }, func(r *Control) { r.Binding.Job.Revision = 0 },
|
|
275
|
+
func(r *Control) { r.Binding.Job.Revision = MaxSafeInteger + 1 }, func(r *Control) { r.Op = "background.confirm" },
|
|
276
|
+
func(r *Control) { r.Op = "background.revoke" },
|
|
277
|
+
} {
|
|
278
|
+
r := controlFixture()
|
|
279
|
+
mutate(&r)
|
|
280
|
+
if _, c := DecodeControl(bytes.NewReader(wire(t, r))); c == "" {
|
|
281
|
+
t.Fatal("mixed/legacy accepted", r)
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
b := string(wire(t, controlFixture()))
|
|
285
|
+
for _, bad := range []string{strings.Replace(b, `"nonce":`, `"nonce":"other","nonce":`, 1), strings.Replace(b, `"binding":`, `"actor":{"uid":1026},"binding":`, 1), strings.Replace(b, `"ticket":`, `"sessionRef":"private","ticket":`, 1), strings.Replace(b, `"revision":1`, `"revision":null`, 1)} {
|
|
286
|
+
if _, c := DecodeControl(strings.NewReader(bad)); c != Invalid {
|
|
287
|
+
t.Fatal(c)
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
r = controlFixture()
|
|
291
|
+
r.Binding.Mode = Background
|
|
292
|
+
d := ref("delegation-1")
|
|
293
|
+
r.Binding.Delegation = &d
|
|
294
|
+
if _, c := DecodeControl(bytes.NewReader(wire(t, r))); c != "" {
|
|
295
|
+
t.Fatal(c)
|
|
296
|
+
}
|
|
297
|
+
r.Op = "background.revoke"
|
|
298
|
+
if _, c := DecodeControl(bytes.NewReader(wire(t, r))); c != "" {
|
|
299
|
+
t.Fatal(c)
|
|
300
|
+
}
|
|
301
|
+
for _, mutate := range []func(*Binding){
|
|
302
|
+
func(b *Binding) { b.Inventory.Version = "1.0.1" }, func(b *Binding) { b.Inventory.Package = "other" },
|
|
303
|
+
func(b *Binding) { b.Inventory.PayloadDigest = strings.Repeat("b", 64) }, func(b *Binding) { b.Inventory.RegistryDigest = strings.Repeat("b", 64) },
|
|
304
|
+
func(b *Binding) { b.Worker.Revision++ }, func(b *Binding) { b.InputSchemaDigest = strings.Repeat("b", 64) },
|
|
305
|
+
func(b *Binding) { b.ApprovalBinding = strings.Repeat("b", 64) }, func(b *Binding) { b.CapabilityDigest = strings.Repeat("b", 64) },
|
|
306
|
+
func(b *Binding) { b.InputDigest = strings.Repeat("b", 64) }, func(b *Binding) { b.Epoch = "epoch-2" },
|
|
307
|
+
func(b *Binding) { b.ParentGrant.Revision++ }, func(b *Binding) { b.Job.Revision++ },
|
|
308
|
+
func(b *Binding) { b.Mode = Background; d := ref("d"); b.Delegation = &d },
|
|
309
|
+
} {
|
|
310
|
+
b := bindingFixture()
|
|
311
|
+
mutate(&b)
|
|
312
|
+
if c := CompareBinding(b, bindingFixture()); c == "" {
|
|
313
|
+
t.Fatal("partial binding match accepted", b)
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
if c := CompareBinding(bindingFixture(), bindingFixture()); c != "" {
|
|
317
|
+
t.Fatal(c)
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
func TestM2InventoryAndOpaqueBindingsAreExact(t *testing.T) {
|
|
322
|
+
for _, mutate := range []func(*Control){
|
|
323
|
+
func(r *Control) { r.Binding.Inventory.Package = "bad-package" },
|
|
324
|
+
func(r *Control) { r.Binding.Inventory.Version = "1.0.0" },
|
|
325
|
+
func(r *Control) { r.Binding.Epoch = "epoch" },
|
|
326
|
+
func(r *Control) { r.Binding.ParentGrant.ID = "grant" },
|
|
327
|
+
func(r *Control) { r.Binding.Job.ID = "job" },
|
|
328
|
+
func(r *Control) { r.Intent.ID = "intent" },
|
|
329
|
+
func(r *Control) { r.Nonce = "nonce" },
|
|
330
|
+
func(r *Control) { r.Ticket = "ticket" },
|
|
331
|
+
} {
|
|
332
|
+
r := controlFixture()
|
|
333
|
+
mutate(&r)
|
|
334
|
+
if _, c := DecodeControl(bytes.NewReader(wire(t, r))); c != Invalid {
|
|
335
|
+
t.Fatal("M2 format loosened", c)
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
func privateFixture() PrivateBinding {
|
|
341
|
+
return PrivateBinding{Binding: bindingFixture(), Actor: Principal{IdentityBasis: "uid-username", UID: 1026, Username: "Name"}, SessionRef: opaque("session-1")}
|
|
342
|
+
}
|
|
343
|
+
func backgroundFixture() BackgroundRecord {
|
|
344
|
+
b := privateFixture()
|
|
345
|
+
b.Binding.Mode = Background
|
|
346
|
+
d := ref("delegation-1")
|
|
347
|
+
b.Binding.Delegation = &d
|
|
348
|
+
b.SessionRef = ""
|
|
349
|
+
return BackgroundRecord{BackgroundSchema: 2, Binding: b, Issuer: b.Actor, CreatedAt: 1000, ExpiresAt: 1000 + DefaultBackgroundTTLMS, NotBefore: 1000, State: "active"}
|
|
350
|
+
}
|
|
351
|
+
func TestPrivateIntentAndBackgroundDiscriminators(t *testing.T) {
|
|
352
|
+
b := privateFixture()
|
|
353
|
+
in := inputFixture()
|
|
354
|
+
b.Binding.InputDigest, _ = InputDigest(in, digest())
|
|
355
|
+
i := Intent{JobSchema: 1, ID: opaque("intent-1"), Revision: 1, Binding: b, Input: in, SummaryDigest: digest(), CreatedAt: 1000, ExpiresAt: 31000}
|
|
356
|
+
if _, c := DecodeIntent(bytes.NewReader(wire(t, i))); c != "" {
|
|
357
|
+
t.Fatal(c)
|
|
358
|
+
}
|
|
359
|
+
i.ExpiresAt++
|
|
360
|
+
if _, c := DecodeIntent(bytes.NewReader(wire(t, i))); c != Invalid {
|
|
361
|
+
t.Fatal(c)
|
|
362
|
+
}
|
|
363
|
+
i.ExpiresAt--
|
|
364
|
+
i.Binding.Binding.InputDigest = strings.Repeat("b", 64)
|
|
365
|
+
if _, c := DecodeIntent(bytes.NewReader(wire(t, i))); c != Invalid {
|
|
366
|
+
t.Fatal(c)
|
|
367
|
+
}
|
|
368
|
+
r := backgroundFixture()
|
|
369
|
+
if _, c := DecodeBackground(bytes.NewReader(wire(t, r))); c != "" {
|
|
370
|
+
t.Fatal(c)
|
|
371
|
+
}
|
|
372
|
+
for _, mutate := range []func(*BackgroundRecord){
|
|
373
|
+
func(r *BackgroundRecord) { r.BackgroundSchema = 1 }, func(r *BackgroundRecord) { r.Binding.SessionRef = "old-session" },
|
|
374
|
+
func(r *BackgroundRecord) { r.Binding.Actor.IdentityBasis = "strict" }, func(r *BackgroundRecord) { r.Binding.Actor.UID = 0 },
|
|
375
|
+
func(r *BackgroundRecord) { r.Issuer.Username = "name" }, func(r *BackgroundRecord) { r.NotBefore = r.ExpiresAt },
|
|
376
|
+
func(r *BackgroundRecord) { r.ExpiresAt = r.CreatedAt + MaxBackgroundTTLMS + 1 },
|
|
377
|
+
func(r *BackgroundRecord) { r.State = "consumed" }, func(r *BackgroundRecord) { r.ExecutionKey = "key" },
|
|
378
|
+
func(r *BackgroundRecord) { r.Reason = "native /secret/file" },
|
|
379
|
+
} {
|
|
380
|
+
r := backgroundFixture()
|
|
381
|
+
mutate(&r)
|
|
382
|
+
if _, c := DecodeBackground(bytes.NewReader(wire(t, r))); c == "" {
|
|
383
|
+
t.Fatal("bad background accepted", r)
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
r.State = "consumed"
|
|
387
|
+
r.ExecutionKey = opaque("execution-1")
|
|
388
|
+
if _, c := DecodeBackground(bytes.NewReader(wire(t, r))); c != "" {
|
|
389
|
+
t.Fatal(c)
|
|
390
|
+
}
|
|
391
|
+
r.State = "revoked"
|
|
392
|
+
r.Reason = Revoked
|
|
393
|
+
if _, c := DecodeBackground(bytes.NewReader(wire(t, r))); c != "" {
|
|
394
|
+
t.Fatal("consumed tombstone lost", c)
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
func jobFixture() Job {
|
|
399
|
+
return Job{Binding: bindingFixture(), State: Pending, Progress: Progress{Phase: "starting"}, AcceptedAt: 1000}
|
|
400
|
+
}
|
|
401
|
+
func TestSafeStateAndProgress(t *testing.T) {
|
|
402
|
+
j := jobFixture()
|
|
403
|
+
if _, c := DecodeJob(bytes.NewReader(wire(t, j))); c != "" {
|
|
404
|
+
t.Fatal(c)
|
|
405
|
+
}
|
|
406
|
+
for _, mutate := range []func(*Job){
|
|
407
|
+
func(j *Job) { j.Reason = "stderr /private" }, func(j *Job) { j.State = "resumed" },
|
|
408
|
+
func(j *Job) { j.State = Succeeded }, func(j *Job) { j.Progress.Sequence = MaxSafeInteger + 1 },
|
|
409
|
+
func(j *Job) { n := uint64(0); j.Progress.TotalUnits = &n; j.Progress.CompletedUnits = 1 },
|
|
410
|
+
func(j *Job) { j.Progress.BytesRead = 64<<20 + 1 }, func(j *Job) { j.Progress.BytesWritten = 1 },
|
|
411
|
+
func(j *Job) { j.Progress.Phase = "/data/file" }, func(j *Job) { j.Drained = true },
|
|
412
|
+
} {
|
|
413
|
+
j := jobFixture()
|
|
414
|
+
mutate(&j)
|
|
415
|
+
if _, c := DecodeJob(bytes.NewReader(wire(t, j))); c == "" {
|
|
416
|
+
t.Fatal("bad job accepted", j)
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
start, finish := uint64(1001), uint64(1002)
|
|
420
|
+
j.StartedAt = &start
|
|
421
|
+
j.FinishedAt = &finish
|
|
422
|
+
j.State = Succeeded
|
|
423
|
+
j.Drained = true
|
|
424
|
+
if _, c := DecodeJob(bytes.NewReader(wire(t, j))); c != "" {
|
|
425
|
+
t.Fatal(c)
|
|
426
|
+
}
|
|
427
|
+
if TransitionAllowed(Succeeded, Running) || TransitionAllowed(Interrupted, Pending) || TransitionAllowed(CleanupRequired, Running) || !TransitionAllowed(Running, CancelRequested) || !TransitionAllowed(Draining, Canceled) {
|
|
428
|
+
t.Fatal("state resurrection")
|
|
429
|
+
}
|
|
430
|
+
if c := ValidateProgress(Progress{Sequence: 1, Phase: "reading", BytesRead: 10}, &Progress{Sequence: 1, Phase: "starting", BytesRead: 1}); c != Invalid {
|
|
431
|
+
t.Fatal("duplicate sequence", c)
|
|
432
|
+
}
|
|
433
|
+
if c := ValidateProgress(Progress{Sequence: 2, Phase: "reading", BytesRead: 0}, &Progress{Sequence: 1, Phase: "starting", BytesRead: 1}); c != Invalid {
|
|
434
|
+
t.Fatal("counter reset", c)
|
|
435
|
+
}
|
|
436
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
package jobcontract
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"bytes"
|
|
5
|
+
"encoding/json"
|
|
6
|
+
"io"
|
|
7
|
+
"reflect"
|
|
8
|
+
"strings"
|
|
9
|
+
"unicode/utf8"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
// Isolated from the runtime helper: this bounded parser has no authority.
|
|
13
|
+
// The ordinary Go decoder accepts case aliases, duplicate keys, nulls and
|
|
14
|
+
// malformed Unicode replacement. A bounded token pass rejects these first.
|
|
15
|
+
func decodeObject(reader io.Reader, dst any, limit int) SafeReason {
|
|
16
|
+
b, err := io.ReadAll(io.LimitReader(reader, int64(limit)+1))
|
|
17
|
+
if err != nil {
|
|
18
|
+
return Invalid
|
|
19
|
+
}
|
|
20
|
+
if len(b) > limit {
|
|
21
|
+
return LimitExceeded
|
|
22
|
+
}
|
|
23
|
+
if !validJSONUnicode(b) {
|
|
24
|
+
return Invalid
|
|
25
|
+
}
|
|
26
|
+
d := json.NewDecoder(bytes.NewReader(b))
|
|
27
|
+
d.UseNumber()
|
|
28
|
+
if !scanShape(d, reflect.TypeOf(dst).Elem(), 0) {
|
|
29
|
+
return Invalid
|
|
30
|
+
}
|
|
31
|
+
if _, err := d.Token(); err != io.EOF {
|
|
32
|
+
return Invalid
|
|
33
|
+
}
|
|
34
|
+
d = json.NewDecoder(bytes.NewReader(b))
|
|
35
|
+
d.DisallowUnknownFields()
|
|
36
|
+
if d.Decode(dst) != nil || d.Decode(new(any)) != io.EOF {
|
|
37
|
+
return Invalid
|
|
38
|
+
}
|
|
39
|
+
return ""
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
func scanShape(d *json.Decoder, t reflect.Type, depth int) bool {
|
|
43
|
+
if depth > 64 {
|
|
44
|
+
return false
|
|
45
|
+
}
|
|
46
|
+
for t != nil && t.Kind() == reflect.Pointer {
|
|
47
|
+
t = t.Elem()
|
|
48
|
+
}
|
|
49
|
+
if t == reflect.TypeOf(json.RawMessage{}) {
|
|
50
|
+
t = nil
|
|
51
|
+
}
|
|
52
|
+
token, err := d.Token()
|
|
53
|
+
if err != nil || token == nil {
|
|
54
|
+
return false
|
|
55
|
+
}
|
|
56
|
+
delim, container := token.(json.Delim)
|
|
57
|
+
if !container {
|
|
58
|
+
return t == nil || (t.Kind() != reflect.Struct && t.Kind() != reflect.Slice)
|
|
59
|
+
}
|
|
60
|
+
switch delim {
|
|
61
|
+
case '{':
|
|
62
|
+
if t != nil && t.Kind() != reflect.Struct {
|
|
63
|
+
return false
|
|
64
|
+
}
|
|
65
|
+
fields := map[string]reflect.Type{}
|
|
66
|
+
if t != nil {
|
|
67
|
+
for i := 0; i < t.NumField(); i++ {
|
|
68
|
+
f := t.Field(i)
|
|
69
|
+
name := strings.Split(f.Tag.Get("json"), ",")[0]
|
|
70
|
+
fields[name] = f.Type
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
seen := map[string]bool{}
|
|
74
|
+
for d.More() {
|
|
75
|
+
k, err := d.Token()
|
|
76
|
+
if err != nil {
|
|
77
|
+
return false
|
|
78
|
+
}
|
|
79
|
+
key, ok := k.(string)
|
|
80
|
+
if !ok || seen[key] {
|
|
81
|
+
return false
|
|
82
|
+
}
|
|
83
|
+
seen[key] = true
|
|
84
|
+
field, known := fields[key]
|
|
85
|
+
if t != nil && !known {
|
|
86
|
+
return false
|
|
87
|
+
}
|
|
88
|
+
if !scanShape(d, field, depth+1) {
|
|
89
|
+
return false
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
end, err := d.Token()
|
|
93
|
+
if err != nil || end != json.Delim('}') {
|
|
94
|
+
return false
|
|
95
|
+
}
|
|
96
|
+
if t != nil {
|
|
97
|
+
for i := 0; i < t.NumField(); i++ {
|
|
98
|
+
tag := strings.Split(t.Field(i).Tag.Get("json"), ",")
|
|
99
|
+
if len(tag) == 1 && !seen[tag[0]] {
|
|
100
|
+
return false
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return true
|
|
105
|
+
case '[':
|
|
106
|
+
if t != nil && t.Kind() != reflect.Slice {
|
|
107
|
+
return false
|
|
108
|
+
}
|
|
109
|
+
var elem reflect.Type
|
|
110
|
+
if t != nil {
|
|
111
|
+
elem = t.Elem()
|
|
112
|
+
}
|
|
113
|
+
for d.More() {
|
|
114
|
+
if !scanShape(d, elem, depth+1) {
|
|
115
|
+
return false
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
end, err := d.Token()
|
|
119
|
+
return err == nil && end == json.Delim(']')
|
|
120
|
+
}
|
|
121
|
+
return false
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
func validJSONUnicode(b []byte) bool {
|
|
125
|
+
if !utf8.Valid(b) {
|
|
126
|
+
return false
|
|
127
|
+
}
|
|
128
|
+
inString := false
|
|
129
|
+
for i := 0; i < len(b); i++ {
|
|
130
|
+
if b[i] == '"' {
|
|
131
|
+
inString = !inString
|
|
132
|
+
continue
|
|
133
|
+
}
|
|
134
|
+
if !inString || b[i] != '\\' {
|
|
135
|
+
continue
|
|
136
|
+
}
|
|
137
|
+
i++
|
|
138
|
+
if i >= len(b) {
|
|
139
|
+
return false
|
|
140
|
+
}
|
|
141
|
+
if b[i] != 'u' {
|
|
142
|
+
continue
|
|
143
|
+
}
|
|
144
|
+
if i+4 >= len(b) {
|
|
145
|
+
return false
|
|
146
|
+
}
|
|
147
|
+
r, ok := unicodeEscape(b[i+1 : i+5])
|
|
148
|
+
if !ok {
|
|
149
|
+
return false
|
|
150
|
+
}
|
|
151
|
+
i += 4
|
|
152
|
+
if r >= 0xdc00 && r <= 0xdfff {
|
|
153
|
+
return false
|
|
154
|
+
}
|
|
155
|
+
if r >= 0xd800 && r <= 0xdbff {
|
|
156
|
+
if i+6 >= len(b) || b[i+1] != '\\' || b[i+2] != 'u' {
|
|
157
|
+
return false
|
|
158
|
+
}
|
|
159
|
+
low, ok := unicodeEscape(b[i+3 : i+7])
|
|
160
|
+
if !ok || low < 0xdc00 || low > 0xdfff {
|
|
161
|
+
return false
|
|
162
|
+
}
|
|
163
|
+
i += 6
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return !inString
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
func unicodeEscape(b []byte) (uint16, bool) {
|
|
170
|
+
var r uint16
|
|
171
|
+
for _, c := range b {
|
|
172
|
+
r <<= 4
|
|
173
|
+
switch {
|
|
174
|
+
case c >= '0' && c <= '9':
|
|
175
|
+
r += uint16(c - '0')
|
|
176
|
+
case c >= 'a' && c <= 'f':
|
|
177
|
+
r += uint16(c - 'a' + 10)
|
|
178
|
+
case c >= 'A' && c <= 'F':
|
|
179
|
+
r += uint16(c - 'A' + 10)
|
|
180
|
+
default:
|
|
181
|
+
return 0, false
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return r, true
|
|
185
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
package jobcontract
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"bytes"
|
|
5
|
+
"crypto/sha256"
|
|
6
|
+
"encoding/binary"
|
|
7
|
+
"encoding/hex"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// Canonical input v1: domain NUL, 32 schema bytes, u32 step count;
|
|
11
|
+
// each step is a u32-length UTF-8 action, u32 segment count, u32-length UTF-8
|
|
12
|
+
// segments, then u64 limit/maxBytes (zero for stat). All integers are big-endian.
|
|
13
|
+
// Validation precedes encoding. No JSON ordering/escapes or Unicode normalization
|
|
14
|
+
// enter the digest. A digest is a binding, NOT a signature/authority proof.
|
|
15
|
+
func encodeInput(in Input, schema string) []byte {
|
|
16
|
+
var b bytes.Buffer
|
|
17
|
+
b.WriteString("synopkgland/m3/input/v1\x00")
|
|
18
|
+
s, _ := hex.DecodeString(schema)
|
|
19
|
+
if schema == "" {
|
|
20
|
+
s = make([]byte, 32)
|
|
21
|
+
}
|
|
22
|
+
b.Write(s)
|
|
23
|
+
write32 := func(n uint32) { var x [4]byte; binary.BigEndian.PutUint32(x[:], n); b.Write(x[:]) }
|
|
24
|
+
writeString := func(s string) { write32(uint32(len(s))); b.WriteString(s) }
|
|
25
|
+
write32(uint32(len(in.Steps)))
|
|
26
|
+
for _, step := range in.Steps {
|
|
27
|
+
writeString(string(step.Action))
|
|
28
|
+
write32(uint32(len(step.Segments)))
|
|
29
|
+
for _, s := range step.Segments {
|
|
30
|
+
writeString(s)
|
|
31
|
+
}
|
|
32
|
+
var n uint64
|
|
33
|
+
if step.Limit != nil {
|
|
34
|
+
n = *step.Limit
|
|
35
|
+
}
|
|
36
|
+
if step.MaxBytes != nil {
|
|
37
|
+
n = *step.MaxBytes
|
|
38
|
+
}
|
|
39
|
+
var x [8]byte
|
|
40
|
+
binary.BigEndian.PutUint64(x[:], n)
|
|
41
|
+
b.Write(x[:])
|
|
42
|
+
}
|
|
43
|
+
return b.Bytes()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
func InputDigest(in Input, schemaDigest string) (string, SafeReason) {
|
|
47
|
+
if !digestPattern.MatchString(schemaDigest) {
|
|
48
|
+
return "", Invalid
|
|
49
|
+
}
|
|
50
|
+
if c := ValidateInput(in); c != "" {
|
|
51
|
+
return "", c
|
|
52
|
+
}
|
|
53
|
+
d := sha256.Sum256(encodeInput(in, schemaDigest))
|
|
54
|
+
return hex.EncodeToString(d[:]), ""
|
|
55
|
+
}
|