@opensoha/contracts 0.1.15 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/auth/catalog_generated.go +2 -2
  2. package/auth/permission-catalog.json +9 -8
  3. package/compat/json-schema-ecosystem-0.1.0.json +1 -1
  4. package/compat/openapi-loose-boundaries-0.1.0.json +58 -1
  5. package/fixtures/openapi/AlertRuleEnvelope/invalid/missing-data.json +1 -0
  6. package/fixtures/openapi/AlertRuleEnvelope/valid/metrics.json +11 -0
  7. package/fixtures/openapi/AlertRuleInput/invalid/missing-name.json +3 -0
  8. package/fixtures/openapi/AlertRuleInput/valid/metrics.json +25 -0
  9. package/fixtures/openapi/AlertRuleRunListEnvelope/invalid/missing-rule-id.json +12 -0
  10. package/fixtures/openapi/AlertRuleRunListEnvelope/valid/items.json +13 -0
  11. package/fixtures/openapi/AlertRuleTestResultEnvelope/invalid/missing-executed-at.json +5 -0
  12. package/fixtures/openapi/AlertRuleTestResultEnvelope/valid/clear.json +10 -0
  13. package/fixtures/openapi/ApplicationRuntimeEnvironment/invalid/unknown-status.json +7 -0
  14. package/fixtures/openapi/ApplicationRuntimeEnvironment/valid/unavailable.json +7 -0
  15. package/fixtures/openapi/ApplicationWorkflowInput/invalid/owner-fields.json +7 -0
  16. package/fixtures/openapi/ApplicationWorkflowInput/valid/minimal.json +9 -0
  17. package/fixtures/openapi/BrandingAssetUploadEnvelope/valid/svg-data-url.json +5 -0
  18. package/fixtures/openapi/BrowserHandoffCompletionEnvelope/invalid/token-leak.json +7 -0
  19. package/fixtures/openapi/BrowserHandoffCompletionEnvelope/valid/completed.json +6 -0
  20. package/fixtures/openapi/BrowserHandoffEnvelope/invalid/missing-principal.json +12 -0
  21. package/fixtures/openapi/BrowserHandoffEnvelope/valid/pending.json +11 -0
  22. package/fixtures/openapi/ChangePasswordRequest/invalid/missing-current-password.json +3 -0
  23. package/fixtures/openapi/ChangePasswordRequest/invalid/short-new-password.json +4 -0
  24. package/fixtures/openapi/ChangePasswordRequest/valid/password.json +4 -0
  25. package/fixtures/openapi/DesktopAuthAttemptCreateRequest/invalid/https-redirect.json +6 -0
  26. package/fixtures/openapi/DesktopAuthAttemptCreateRequest/invalid/localhost-redirect.json +6 -0
  27. package/fixtures/openapi/DesktopAuthAttemptCreateRequest/invalid/plain-challenge.json +6 -0
  28. package/fixtures/openapi/DesktopAuthAttemptCreateRequest/invalid/privileged-port.json +6 -0
  29. package/fixtures/openapi/DesktopAuthAttemptCreateRequest/invalid/short-callback.json +6 -0
  30. package/fixtures/openapi/DesktopAuthAttemptCreateRequest/valid/loopback.json +6 -0
  31. package/fixtures/openapi/DesktopAuthAttemptEnvelope/invalid/missing-expiry.json +6 -0
  32. package/fixtures/openapi/DesktopAuthAttemptEnvelope/valid/attempt.json +7 -0
  33. package/fixtures/openapi/DesktopAuthAttemptExchangeRequest/invalid/short-verifier.json +4 -0
  34. package/fixtures/openapi/DesktopAuthAttemptExchangeRequest/valid/exchange.json +4 -0
  35. package/fixtures/openapi/IdentityApplication/invalid/missing-id.json +7 -0
  36. package/fixtures/openapi/IdentityApplication/valid/full.json +30 -0
  37. package/fixtures/openapi/IdentityApplicationEnvelope/invalid/missing-data.json +1 -0
  38. package/fixtures/openapi/IdentityApplicationEnvelope/valid/minimal.json +10 -0
  39. package/fixtures/openapi/IdentityApplicationLaunchListEnvelope/invalid/missing-user.json +11 -0
  40. package/fixtures/openapi/IdentityApplicationLaunchListEnvelope/valid/minimal.json +12 -0
  41. package/fixtures/openapi/LogQuery/invalid/empty-data-source-id.json +7 -0
  42. package/fixtures/openapi/LogQuery/valid/durable-data-source.json +14 -0
  43. package/fixtures/openapi/ManifestPackage/invalid/missing-application.json +12 -0
  44. package/fixtures/openapi/ManifestPackage/valid/service-scoped.json +29 -0
  45. package/fixtures/openapi/OIDCClientInput/valid/generated-client-id.json +8 -0
  46. package/fixtures/openapi/OIDCClientSecretRevealEnvelope/invalid/missing-secret.json +6 -0
  47. package/fixtures/openapi/OIDCClientSecretRevealEnvelope/valid/reveal.json +7 -0
  48. package/fixtures/openapi/PasswordChangeResult/invalid/unexpected-status.json +3 -0
  49. package/fixtures/openapi/PasswordChangeResult/valid/ok.json +3 -0
  50. package/fixtures/openapi/PortalApplicationListEnvelope/invalid/missing-items.json +1 -0
  51. package/fixtures/openapi/PortalApplicationListEnvelope/valid/minimal.json +12 -0
  52. package/fixtures/openapi/PortalBootstrapEnvelope/invalid/missing-security.json +17 -0
  53. package/fixtures/openapi/PortalBootstrapEnvelope/valid/minimal.json +31 -0
  54. package/fixtures/openapi/PortalLaunchDecisionEnvelope/invalid/missing-launch-url.json +14 -0
  55. package/fixtures/openapi/PortalLaunchDecisionEnvelope/valid/desktop-handoff.json +16 -0
  56. package/fixtures/openapi/PortalLaunchRequest/invalid/unknown-surface.json +3 -0
  57. package/fixtures/openapi/PortalLaunchRequest/valid/default-web.json +1 -0
  58. package/fixtures/openapi/PortalLaunchRequest/valid/desktop.json +3 -0
  59. package/fixtures/openapi/PortalSecuritySummaryEnvelope/invalid/missing-session-count.json +15 -0
  60. package/fixtures/openapi/PortalSecuritySummaryEnvelope/valid/minimal.json +16 -0
  61. package/fixtures/openapi/ScopeGrantInput/invalid/delivery-missing-business-line.json +7 -0
  62. package/fixtures/openapi/ScopeGrantInput/invalid/platform-missing-clusters.json +7 -0
  63. package/fixtures/openapi/ScopeGrantInput/valid/platform.json +8 -0
  64. package/fixtures/openapi/SoftwarePackage/valid/software-package.json +6 -0
  65. package/fixtures/openapi/SoftwarePackageDownloadRecord/invalid/negative-duration.json +6 -0
  66. package/fixtures/openapi/SoftwarePackageDownloadRecord/valid/software-package-download-record.json +8 -0
  67. package/fixtures/openapi/SoftwarePackageURLImportRequest/valid/software-package-url-import-request.json +4 -0
  68. package/fixtures/openapi/SoftwareStorage/invalid/software-storage.json +1 -1
  69. package/fixtures/openapi/SoftwareStorage/valid/software-storage.json +13 -1
  70. package/fixtures/openapi/SystemIntegrationCreateRequest/invalid/s3-storage-missing-name.json +5 -0
  71. package/fixtures/openapi/SystemIntegrationCreateRequest/valid/s3-software-storage.json +18 -0
  72. package/fixtures/openapi/UpdateProfileRequest/invalid/invalid-avatar-fit.json +5 -0
  73. package/fixtures/openapi/UpdateProfileRequest/invalid/missing-email.json +3 -0
  74. package/fixtures/openapi/UpdateProfileRequest/valid/profile.json +7 -0
  75. package/gen/go/sohaapi/client.go +210 -5
  76. package/gen/go/sohaapi/client_test.go +128 -5
  77. package/gen/go/sohaapi/types.go +1105 -132
  78. package/gen/go/sohaapi/types_test.go +22 -0
  79. package/gen/ts/sohaapi/index.ts +2007 -34
  80. package/openapi/soha-api.json +4169 -136
  81. package/openapi/soha-api.yaml +2219 -9
  82. package/openapi/spec_generated.go +3 -3
  83. package/package.json +1 -1
@@ -6,6 +6,7 @@ import (
6
6
  "io"
7
7
  "net/http"
8
8
  "net/http/httptest"
9
+ "strings"
9
10
  "testing"
10
11
  "time"
11
12
  )
@@ -155,9 +156,9 @@ func TestExchangeDockerHostAgentEnrollmentIsPublicAndReturnsCredentials(t *testi
155
156
  w.WriteHeader(http.StatusCreated)
156
157
  writeJSON(t, w, map[string]any{"data": map[string]any{
157
158
  "hostId": "host-1", "operationId": "operation-1", "agentId": "host-1",
158
- "agentBearerToken": "agent-secret-012345678901234567890",
159
+ "agentBearerToken": "agent-secret-012345678901234567890",
159
160
  "runtimeBearerToken": "runtime-secret-012345678901234567",
160
- "issuedAt": issuedAt,
161
+ "issuedAt": issuedAt,
161
162
  }})
162
163
  })
163
164
 
@@ -331,7 +332,7 @@ func TestComputeTaskCenterClientSurface(t *testing.T) {
331
332
  case 1:
332
333
  assertCommonRequest(t, r, http.MethodGet, "/api/v1/compute/tasks")
333
334
  assertQuery(t, r, map[string]string{
334
- "domain": "virtualization", "resourceKind": "cluster", "resourceId": "cluster-1", "limit": "1",
335
+ "domain": "virtualization", "resourceKind": "cluster", "resourceId": "cluster-1", "sortBy": "status", "sortOrder": "desc", "limit": "1",
335
336
  })
336
337
  writeJSON(t, w, map[string]any{"items": []any{}})
337
338
  case 2:
@@ -344,12 +345,18 @@ func TestComputeTaskCenterClientSurface(t *testing.T) {
344
345
  }}})
345
346
  case 4:
346
347
  assertCommonRequest(t, r, http.MethodPost, "/api/v1/compute/tasks/virtualization/task%2Fone/cancel")
348
+ if key := r.Header.Get("Idempotency-Key"); !strings.HasPrefix(key, "compute-") {
349
+ t.Fatalf("cancel Idempotency-Key = %q", key)
350
+ }
347
351
  if body := decodeJSONRequestBody[ComputeTaskMutationRequest](t, r); body.Reason != "operator request" {
348
352
  t.Fatalf("cancel reason = %q", body.Reason)
349
353
  }
350
354
  writeJSON(t, w, computeTaskEnvelopeFixture("task/one"))
351
355
  case 5:
352
356
  assertCommonRequest(t, r, http.MethodPost, "/api/v1/compute/tasks/virtualization/task%2Fone/retry")
357
+ if key := r.Header.Get("Idempotency-Key"); key != "retry-key-1" {
358
+ t.Fatalf("retry Idempotency-Key = %q", key)
359
+ }
353
360
  writeJSON(t, w, computeTaskEnvelopeFixture("task/two"))
354
361
  default:
355
362
  t.Fatalf("unexpected request %s %s", r.Method, r.URL.Path)
@@ -357,7 +364,7 @@ func TestComputeTaskCenterClientSurface(t *testing.T) {
357
364
  })
358
365
 
359
366
  items, err := client.ListComputeTasks(context.Background(), ListComputeTasksParams{
360
- Domain: ComputeTaskDomainVirtualization, ResourceKind: "cluster", ResourceID: "cluster-1", Limit: 1,
367
+ Domain: ComputeTaskDomainVirtualization, ResourceKind: "cluster", ResourceID: "cluster-1", SortBy: "status", SortOrder: ListComputeTasksParamsSortOrder("desc"), Limit: 1,
361
368
  })
362
369
  if err != nil || len(items.Items) != 0 {
363
370
  t.Fatalf("ListComputeTasks = %#v, %v", items, err)
@@ -371,11 +378,127 @@ func TestComputeTaskCenterClientSurface(t *testing.T) {
371
378
  if _, err := client.CancelComputeTask(context.Background(), ComputeTaskDomainVirtualization, "task/one", ComputeTaskMutationRequest{Reason: "operator request"}); err != nil {
372
379
  t.Fatalf("CancelComputeTask returned error: %v", err)
373
380
  }
374
- if task, err := client.RetryComputeTask(context.Background(), ComputeTaskDomainVirtualization, "task/one", ComputeTaskMutationRequest{}); err != nil || task.ID != "task/two" {
381
+ if task, err := client.RetryComputeTaskWithKey(context.Background(), ComputeTaskDomainVirtualization, "task/one", "retry-key-1", ComputeTaskMutationRequest{}); err != nil || task.ID != "task/two" {
375
382
  t.Fatalf("RetryComputeTask = %#v, %v", task, err)
376
383
  }
377
384
  }
378
385
 
386
+ func TestComputeInventoryClientSurface(t *testing.T) {
387
+ requests := 0
388
+ client := newTestClient(t, func(w http.ResponseWriter, r *http.Request) {
389
+ requests++
390
+ switch requests {
391
+ case 1:
392
+ assertCommonRequest(t, r, http.MethodGet, "/api/v1/compute/capabilities")
393
+ writeJSON(t, w, map[string]any{"data": map[string]any{"generation": 1, "features": []any{}}})
394
+ case 2:
395
+ assertCommonRequest(t, r, http.MethodGet, "/api/v1/compute/overview")
396
+ writeJSON(t, w, map[string]any{"data": map[string]any{"attention": []any{}, "providerHealth": []any{}, "partial": false, "warnings": []any{}}})
397
+ case 3:
398
+ assertCommonRequest(t, r, http.MethodGet, "/api/v1/compute/access-sources")
399
+ assertQuery(t, r, map[string]string{"sourceType": "virtualization_connection", "providerKey": "pve", "cursor": "next", "limit": "10"})
400
+ writeJSON(t, w, map[string]any{"items": []any{}})
401
+ case 4:
402
+ assertCommonRequest(t, r, http.MethodGet, "/api/v1/compute/providers")
403
+ assertQuery(t, r, map[string]string{"domain": "virtualization", "source": "builtin", "limit": "10"})
404
+ writeJSON(t, w, map[string]any{"items": []any{}})
405
+ case 5:
406
+ assertCommonRequest(t, r, http.MethodGet, "/api/v1/compute/provider-instances")
407
+ assertQuery(t, r, map[string]string{"domain": "virtualization", "providerKey": "pve", "limit": "10"})
408
+ writeJSON(t, w, map[string]any{"items": []any{}})
409
+ case 6:
410
+ assertCommonRequest(t, r, http.MethodGet, "/api/v1/compute/provider-instances/virtualization/pve/connection%2Fone")
411
+ writeJSON(t, w, map[string]any{"data": map[string]any{}})
412
+ case 7:
413
+ assertCommonRequest(t, r, http.MethodPost, "/api/v1/compute/provider-instances/virtualization/pve/connection%2Fone/health-checks")
414
+ if key := r.Header.Get("Idempotency-Key"); key != "health-key-1" {
415
+ t.Fatalf("health Idempotency-Key = %q", key)
416
+ }
417
+ writeJSON(t, w, computeTaskEnvelopeFixture("health-task"))
418
+ case 8:
419
+ assertCommonRequest(t, r, http.MethodPost, "/api/v1/compute/provider-instances/virtualization/pve/connection%2Fone/discoveries")
420
+ if key := r.Header.Get("Idempotency-Key"); key != "discover-key-1" {
421
+ t.Fatalf("discover Idempotency-Key = %q", key)
422
+ }
423
+ writeJSON(t, w, computeTaskEnvelopeFixture("discover-task"))
424
+ case 9:
425
+ assertCommonRequest(t, r, http.MethodGet, "/api/v1/compute/resources/virtualization/vm/vm%2Fone")
426
+ writeJSON(t, w, map[string]any{"data": map[string]any{"id": "vm/one"}})
427
+ case 10:
428
+ assertCommonRequest(t, r, http.MethodGet, "/api/v1/compute/resources/virtualization/vm/vm%2Fone/relations")
429
+ assertQuery(t, r, map[string]string{"cursor": "next", "limit": "20"})
430
+ writeJSON(t, w, map[string]any{"data": map[string]any{"resource": map[string]any{"domain": "virtualization", "kind": "vm", "id": "vm/one", "displayName": "vm-one"}, "relations": []any{}}})
431
+ case 11:
432
+ assertCommonRequest(t, r, http.MethodPost, "/api/v1/compute/resources/virtualization/vm/vm%2Fone/actions/start")
433
+ if key := r.Header.Get("Idempotency-Key"); key != "action-key-1" {
434
+ t.Fatalf("action Idempotency-Key = %q", key)
435
+ }
436
+ writeJSON(t, w, computeTaskEnvelopeFixture("action-task"))
437
+ default:
438
+ t.Fatalf("unexpected request %s %s", r.Method, r.URL.Path)
439
+ }
440
+ })
441
+
442
+ ctx := context.Background()
443
+ if _, err := client.GetComputeCapabilities(ctx); err != nil {
444
+ t.Fatal(err)
445
+ }
446
+ if _, err := client.GetComputeOverview(ctx); err != nil {
447
+ t.Fatal(err)
448
+ }
449
+ if _, err := client.ListComputeAccessSources(ctx, ListComputeAccessSourcesParams{SourceType: ComputeAccessSourceTypeVirtualizationConnection, ProviderKey: "pve", Cursor: "next", Limit: 10}); err != nil {
450
+ t.Fatal(err)
451
+ }
452
+ if _, err := client.ListComputeProviders(ctx, ListComputeProvidersParams{Domain: ComputeProviderDomainVirtualization, Source: ComputeProviderSourceBuiltin, Limit: 10}); err != nil {
453
+ t.Fatal(err)
454
+ }
455
+ if _, err := client.ListComputeProviderInstances(ctx, ListComputeProviderInstancesParams{Domain: ComputeProviderDomainVirtualization, ProviderKey: "pve", Limit: 10}); err != nil {
456
+ t.Fatal(err)
457
+ }
458
+ if _, err := client.GetComputeProviderInstance(ctx, ComputeProviderDomainVirtualization, "pve", "connection/one"); err != nil {
459
+ t.Fatal(err)
460
+ }
461
+ if _, err := client.CheckComputeProviderInstanceHealth(ctx, ComputeProviderDomainVirtualization, "pve", "connection/one", "health-key-1", ComputeProviderReadRequest{ExpectedGeneration: 1}); err != nil {
462
+ t.Fatal(err)
463
+ }
464
+ if _, err := client.DiscoverComputeProviderInstance(ctx, ComputeProviderDomainVirtualization, "pve", "connection/one", "discover-key-1", ComputeProviderDiscoverRequest{ExpectedGeneration: 1}); err != nil {
465
+ t.Fatal(err)
466
+ }
467
+ if _, err := client.GetComputeResource(ctx, ComputeDomainVirtualization, ComputeResourceKindVM, "vm/one"); err != nil {
468
+ t.Fatal(err)
469
+ }
470
+ if _, err := client.ListComputeResourceRelations(ctx, ComputeDomainVirtualization, ComputeResourceKindVM, "vm/one", ListComputeResourceRelationsParams{Cursor: "next", Limit: 20}); err != nil {
471
+ t.Fatal(err)
472
+ }
473
+ if _, err := client.ExecuteComputeResourceAction(ctx, ComputeDomainVirtualization, ComputeResourceKindVM, "vm/one", "start", "action-key-1", ComputeResourceActionRequest{}); err != nil {
474
+ t.Fatal(err)
475
+ }
476
+ }
477
+
478
+ func TestStreamComputeTask(t *testing.T) {
479
+ client := newTestClient(t, func(w http.ResponseWriter, r *http.Request) {
480
+ if r.Method != http.MethodGet || r.URL.EscapedPath() != "/api/v1/compute/tasks/virtualization/task%2Fone/stream" {
481
+ t.Fatalf("request = %s %s", r.Method, r.URL.EscapedPath())
482
+ }
483
+ if accept := r.Header.Get("Accept"); accept != "text/event-stream" {
484
+ t.Fatalf("Accept = %q", accept)
485
+ }
486
+ if r.Header.Get("Authorization") != "Bearer test-token" || r.Header.Get("User-Agent") != "sohaapi-test" {
487
+ t.Fatalf("unexpected authenticated stream headers: %#v", r.Header)
488
+ }
489
+ _, _ = io.WriteString(w, "event: snapshot\ndata: {\"type\":\"snapshot\",\"observedAt\":\"2026-08-24T12:00:00Z\",\"sequence\":1}\n\n")
490
+ })
491
+
492
+ var events []ComputeTaskStreamEvent
493
+ err := client.StreamComputeTask(context.Background(), ComputeTaskDomainVirtualization, "task/one", func(event ComputeTaskStreamEvent) error {
494
+ events = append(events, event)
495
+ return nil
496
+ })
497
+ if err != nil || len(events) != 1 || events[0].Sequence != 1 {
498
+ t.Fatalf("StreamComputeTask events=%#v err=%v", events, err)
499
+ }
500
+ }
501
+
379
502
  func TestResourceLogClientSurface(t *testing.T) {
380
503
  requests := []string{
381
504
  "/api/v1/clusters/cluster%2Fone/logs/query",