@tdxvolt/volt-client-grpc 0.20.31 → 0.20.34

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/lib/index.cjs CHANGED
@@ -1043,9 +1043,12 @@ import "tdx/volt_api/volt/v1/volt.proto";
1043
1043
 
1044
1044
  // The Drive API allows clients to create and manage Volt Drive resources.
1045
1045
  service DriveAPI {
1046
- // Create or update a drive connection resource.
1047
- // This is a privileged API call and requires volt:api-call / volt:save-drive-instance permission.
1048
- rpc SaveDriveInstance(SaveDriveInstanceRequest) returns (SaveDriveInstanceResponse);
1046
+ // Create or update a drive connection resource.
1047
+ // This is a privileged API call and requires volt:api-call / volt:save-drive-instance permission.
1048
+ rpc SaveDriveInstance(SaveDriveInstanceRequest) returns (SaveDriveInstanceResponse);
1049
+
1050
+ // Stream the FolderSync status of the drive instances on this Volt that host \`synapse_id\`. Busy means the local ingest/materialise queue is working. If there is no instance on this Volt, the stream reports absent.
1051
+ rpc WatchDriveInstanceStatus(stream WatchDriveInstanceStatusRequest) returns (stream WatchDriveInstanceStatusResponse);
1049
1052
  }
1050
1053
 
1051
1054
  message SaveDriveInstanceRequest {
@@ -1106,6 +1109,47 @@ message SaveDriveInstanceResponse {
1106
1109
  Resource resource = 2;
1107
1110
  }
1108
1111
 
1112
+ enum DriveInstanceState {
1113
+ // No drive instance for this synapse is running on this Volt, so this Volt has nothing to say about its sync progress.
1114
+ DRIVE_INSTANCE_STATE_ABSENT = 0;
1115
+
1116
+ // An instance is running with nothing queued.
1117
+ DRIVE_INSTANCE_STATE_IDLE = 1;
1118
+
1119
+ // Files are queued, in flight, or the initial scan is running.
1120
+ DRIVE_INSTANCE_STATE_BUSY = 2;
1121
+ }
1122
+
1123
+ // FolderSync work on this Volt for a drive synapse.
1124
+ message DriveInstanceStatus {
1125
+ DriveInstanceState state = 1;
1126
+
1127
+ // Distinct files admitted to the operation currently underway, summed over every instance on this Volt that hosts the synapse. Grows as more work is discovered and never shrinks mid-operation. Zero once the drive settles.
1128
+ uint32 total_count = 2;
1129
+
1130
+ // How many of \`total_count\` have reached a terminal state.
1131
+ uint32 completed_count = 3;
1132
+ }
1133
+
1134
+ message WatchDriveInstanceStatusStart {
1135
+ // The id of the drive synapse (drive database) to watch.
1136
+ string synapse_id = 1;
1137
+ }
1138
+
1139
+ message WatchDriveInstanceStatusRequest {
1140
+ oneof payload {
1141
+ WatchDriveInstanceStatusStart start = 1;
1142
+ bool stop = 2;
1143
+ }
1144
+ }
1145
+
1146
+ message WatchDriveInstanceStatusResponse {
1147
+ oneof result {
1148
+ tdx.volt_api.volt.v1.Status status = 1;
1149
+ DriveInstanceStatus update = 2;
1150
+ }
1151
+ }
1152
+
1109
1153
  `;
1110
1154
  const file = `syntax = "proto3";
1111
1155
 
@@ -1770,6 +1814,12 @@ service SyncAPI {
1770
1814
  // Watch synapse paths for changes.
1771
1815
  rpc WatchSynapsePath(stream WatchSynapsePathRequest) returns (stream WatchSynapsePathResponse);
1772
1816
 
1817
+ // Get the state of a synapse document on this Volt. Reports whether the content this Volt holds matches the \`__hash\` advertised in the synapse metadata.
1818
+ rpc GetSynapseDocumentState(GetSynapseDocumentStateRequest) returns (GetSynapseDocumentStateResponse);
1819
+
1820
+ // Watch synapse documents for state changes. The server sends the current state of every watched document before any subsequent transitions, so a watcher started after content lands does not miss it.
1821
+ rpc WatchSynapseDocumentState(stream WatchSynapseDocumentStateRequest) returns (stream WatchSynapseDocumentStateResponse);
1822
+
1773
1823
  // Write a single value to a given synapse JSON path.
1774
1824
  rpc WriteSynapsePath(WriteSynapsePathRequest) returns (WriteSynapsePathResponse);
1775
1825
 
@@ -1980,8 +2030,8 @@ message SetSynapseDocumentMetadataRequest {
1980
2030
  // Any additional application-specific JSON to attach to the document.
1981
2031
  string json = 4;
1982
2032
 
1983
- // Set to true when the document content is already present (content-first) or the document is intentionally empty, so the server bootstraps \`__hash\` immediately. Leave false (the default) when content will be written after this call.
1984
- bool content_ready = 6;
2033
+ // Set to true to publish \`__hash\` immediately, because the content is already present (content-first) or the document is intentionally empty. Leave false (the default) when content will be written after this call, in which case the server publishes \`__hash\` once that content arrives. This is creator intent at create time; it says nothing about whether other Volts hold the content (see GetSynapseDocumentState).
2034
+ bool publish_hash = 6;
1985
2035
 
1986
2036
  // For blob documents, the content hash to bind. The server verifies the blob is stored (or the hash is sha256 of empty bytes) and writes \`__hash\`. Omit for a metadata-first create. Must not be set for map/array/text documents; the server computes those hashes from Yjs content.
1987
2037
  string blob_hash = 7;
@@ -2054,9 +2104,6 @@ message SyncDocumentResponse {
2054
2104
 
2055
2105
  // Parameters to start watching synapse paths. Sent as the first message.
2056
2106
  message WatchSynapsePathStart {
2057
- // DEPRECATED: Use synapse_id instead.
2058
- string database_id = 1;
2059
-
2060
2107
  // The id of the synapse that contains the document.
2061
2108
  string synapse_id = 4;
2062
2109
 
@@ -2217,16 +2264,100 @@ message RevertSyncDocumentVersionResponse {
2217
2264
  string version_id = 2;
2218
2265
  }
2219
2266
 
2267
+ // The state of a synapse document. \`__hash\` in the synapse metadata says what the content is; this says whether this Volt holds it yet. Metadata replicates independently of content, so a document can be ANNOUNCED here and READY on the Volt that produced it.
2268
+ enum SynapseDocumentState {
2269
+ SYNAPSE_DOCUMENT_STATE_UNKNOWN = 0;
2270
+
2271
+ // No metadata entry for this document on this Volt.
2272
+ SYNAPSE_DOCUMENT_STATE_ABSENT = 1;
2273
+
2274
+ // Metadata entry exists but no \`__hash\` has been published yet, so no content has been committed. See SetSynapseDocumentMetadata.publish_hash.
2275
+ SYNAPSE_DOCUMENT_STATE_DRAFT = 2;
2276
+
2277
+ // \`__hash\` is published but the content this Volt holds does not match it. The content is still in flight; wait for READY before reading it.
2278
+ SYNAPSE_DOCUMENT_STATE_ANNOUNCED = 3;
2279
+
2280
+ // The content this Volt holds matches \`__hash\`. The document can be read.
2281
+ SYNAPSE_DOCUMENT_STATE_READY = 4;
2282
+
2283
+ // The metadata entry was removed.
2284
+ SYNAPSE_DOCUMENT_STATE_DELETED = 5;
2285
+ }
2286
+
2287
+ message GetSynapseDocumentStateRequest {
2288
+ // The id of the synapse that contains the document.
2289
+ string synapse_id = 1;
2290
+
2291
+ // The id of the document to query.
2292
+ string document_id = 2;
2293
+ }
2294
+
2295
+ message GetSynapseDocumentStateResponse {
2296
+ // Details of any error that occurred on the call.
2297
+ tdx.volt_api.volt.v1.Status status = 1;
2298
+
2299
+ // The state of the document.
2300
+ SynapseDocumentState state = 2;
2301
+
2302
+ // The content hash advertised in the synapse metadata (\`__hash\`). Empty for ABSENT and DRAFT documents.
2303
+ string hash = 3;
2304
+
2305
+ // The content hash this Volt actually holds. Empty when no content has landed here yet. Equal to \`hash\` when the state is READY.
2306
+ string local_hash = 4;
2307
+ }
2308
+
2309
+ // Parameters to start watching synapse document state. Sent as the first message.
2310
+ message WatchSynapseDocumentStateStart {
2311
+ // The id of the synapse to watch.
2312
+ string synapse_id = 1;
2313
+
2314
+ // The ids of the documents to watch. Leave empty to watch every document in the synapse, including documents added after the watch starts.
2315
+ repeated string document_id = 2;
2316
+ }
2317
+
2318
+ message WatchSynapseDocumentStateRequest {
2319
+ oneof payload {
2320
+ // Start watching; must be sent as the first message.
2321
+ WatchSynapseDocumentStateStart start = 1;
2322
+
2323
+ // Request to stop the watch.
2324
+ bool stop = 2;
2325
+ }
2326
+ }
2327
+
2328
+ message WatchSynapseDocumentStateUpdate {
2329
+ // The id of the document whose state changed.
2330
+ string document_id = 1;
2331
+
2332
+ SynapseDocumentState state = 2;
2333
+
2334
+ // The content hash advertised in the synapse metadata (\`__hash\`).
2335
+ string hash = 3;
2336
+
2337
+ // The content hash this Volt actually holds.
2338
+ string local_hash = 4;
2339
+ }
2340
+
2341
+ message WatchSynapseDocumentStateResponse {
2342
+ oneof result {
2343
+ // Details of any error that occurred on the call.
2344
+ tdx.volt_api.volt.v1.Status status = 1;
2345
+
2346
+ // A document state update.
2347
+ WatchSynapseDocumentStateUpdate update = 2;
2348
+ }
2349
+ }
2350
+
2220
2351
  message HasSynapseBlobRequest {
2221
2352
  // The id of the synapse that stores the blob.
2222
2353
  string synapse_id = 1;
2223
2354
 
2224
- // sha256 of the raw file bytes, encoded as unpadded base64url (same family
2225
- // as VoltDrive content hashes).
2355
+ // SHA-256 of the raw file bytes, encoded as unpadded base64url.
2226
2356
  string hash = 2;
2227
2357
  }
2228
2358
 
2229
2359
  message HasSynapseBlobResponse {
2360
+ // Details of any error that occurred on the call.
2230
2361
  tdx.volt_api.volt.v1.Status status = 1;
2231
2362
 
2232
2363
  // True if a blob with this hash is already stored.
@@ -2234,6 +2365,7 @@ message HasSynapseBlobResponse {
2234
2365
  }
2235
2366
 
2236
2367
  message PutSynapseBlobStart {
2368
+ // The id of the synapse that stores the blob.
2237
2369
  string synapse_id = 1;
2238
2370
 
2239
2371
  // Expected sha256 (base64url) of the concatenated payload bytes.
@@ -2264,13 +2396,20 @@ message PutSynapseBlobResponse {
2264
2396
  }
2265
2397
 
2266
2398
  message GetSynapseBlobRequest {
2399
+ // The id of the synapse that stores the blob.
2267
2400
  string synapse_id = 1;
2401
+
2402
+ // SHA-256 of the raw file bytes, encoded as unpadded base64url.
2268
2403
  string hash = 2;
2269
2404
  }
2270
2405
 
2271
2406
  message GetSynapseBlobResponse {
2407
+ // The next chunk of blob data or details of any error that occurred on the call.
2272
2408
  oneof payload {
2409
+ // The next chunk of blob data.
2273
2410
  bytes block = 1;
2411
+
2412
+ // Details of any error that occurred on the call.
2274
2413
  tdx.volt_api.volt.v1.Status status = 2;
2275
2414
  }
2276
2415
  }
@@ -2648,6 +2787,9 @@ message VoltParameters {
2648
2787
 
2649
2788
  // Optional per-method gRPC rate limits (see GrpcRpcRateLimit). Keyed by peer identity or fingerprint.
2650
2789
  repeated GrpcRpcRateLimit grpc_rpc_rate_limit = 57;
2790
+
2791
+ // Deadline in milliseconds for outbound unary gRPC calls made by this Volt (relay, synapse, mirroring, drive and DID registry calls). If unset or zero, the built-in defaults are used.
2792
+ uint32 grpc_unary_deadline = 58;
2651
2793
  }
2652
2794
 
2653
2795
  message VoltEndpoint {
@@ -3184,6 +3326,14 @@ service VoltAPI {
3184
3326
  // This is a privileged API call and requires volt:api-call / volt:save-http-file-server permission.
3185
3327
  rpc SaveHttpFileServer(SaveHttpFileServerRequest) returns (SaveHttpFileServerResponse);
3186
3328
 
3329
+ // Publish a local filesystem folder over HTTP, optionally via a connected relay.
3330
+ // This is a privileged API call and requires volt:api-call / volt:publish-folder permission. Updating an existing publication additionally requires volt:resource-write on the published-folder resource.
3331
+ // On failure any resource this call created is removed, so a publication is never left half-built. Updates to an existing publication are idempotent: retry the same request to recover from a partial failure.
3332
+ rpc PublishFolder(PublishFolderRequest) returns (PublishFolderResponse);
3333
+
3334
+ // Remove a folder published by PublishFolder. Remote forwarder and OIDC resources are deleted first; the local file-server record is kept if remote cleanup fails so the operation can be retried. DeleteResource on a volt:published-folder resource performs the same remote cleanup.
3335
+ rpc UnpublishFolder(UnpublishFolderRequest) returns (UnpublishFolderResponse);
3336
+
3187
3337
  // Create or update an HTTP forwarder resource.
3188
3338
  // This is a privileged API call and requires volt:api-call / volt:save-http-forwarder permission.
3189
3339
  rpc SaveHttpForwarder(SaveHttpForwarderRequest) returns (SaveHttpForwarderResponse);
@@ -4188,7 +4338,7 @@ message SaveHttpForwarderRequest {
4188
4338
  // Set to indicate the resource attributes should be purged before saving the resource.
4189
4339
  bool purge_attributes = 4;
4190
4340
 
4191
- // The domain to forward requests to.
4341
+ // FQDN of the public Host this forwarder matches (e.g. wiki.tdxid.com). Do not include a scheme or port. Must not be this Volt's own hostname (use \`path\` for own-host forwarding). Optional when \`path\` is set.
4192
4342
  string domain = 5;
4193
4343
 
4194
4344
  // The host to forward requests to.
@@ -4200,7 +4350,7 @@ message SaveHttpForwarderRequest {
4200
4350
  // Set to indicate that the host header should reflect the proxy domain rather than the target host.
4201
4351
  bool forward_host = 8;
4202
4352
 
4203
- // Optional path prefix (e.g. "/myapp") for path-based forwarding. May be used on its own (path forwarding on the Volt's own host) or together with \`domain\` (sub-domain + path, e.g. sub.acme.com/myapp). At least one of \`domain\` or \`path\` must be set.
4353
+ // Optional path prefix (e.g. "/myapp") for path-based forwarding. May be used on its own (path forwarding on the Volt's own host) or together with \`domain\` (host + path, e.g. app.acme.com/myapp). At least one of \`domain\` or \`path\` must be set.
4204
4354
  string path = 9;
4205
4355
 
4206
4356
  // When a \`path\` prefix is configured, keep that prefix on the request path when forwarding. The default (false) is standard reverse-proxy behaviour: the prefix is stripped so the target receives the request at its own root (e.g. "/drive/assets/x.js" -> "/assets/x.js"), which suits plain static file servers and root-mounted backends. Set to true for targets that are themselves configured under the same sub-path and expect to receive the prefix. The \`X-Forwarded-Prefix\` header is always sent.
@@ -4209,7 +4359,7 @@ message SaveHttpForwarderRequest {
4209
4359
  // When true, incoming HTTP requests to this forwarder must carry a valid authenticated session (established via the OIDC sign-in flow) and pass the policy check before being proxied, except for the public-path and manifest exceptions on \`auth_public_paths\`. Unauthenticated top-level document navigations are redirected to the configured OpenID Provider; other unauthenticated requests receive 401. An authenticated session that fails the policy check receives 403. The Volt session cookie is stripped from the HTTP hop to the target. WebSocket and SSE upgrades are not gated.
4210
4360
  bool auth_enabled = 11;
4211
4361
 
4212
- // OpenID Provider issuer URL used for discovery (\`<issuer>/.well-known/openid-configuration\`). May be a Volt acting as an OpenID Provider, or any external OIDC provider. Required when \`auth_enabled\` is set.
4362
+ // OpenID Provider issuer URL used for discovery (\`[issuer]/.well-known/openid-configuration\`). May be a Volt acting as an OpenID Provider, or any external OIDC provider. Required when \`auth_enabled\` is set.
4213
4363
  string oidc_issuer = 12;
4214
4364
 
4215
4365
  // OAuth 2.0 client identifier registered with the OpenID Provider.
@@ -4229,6 +4379,10 @@ message SaveHttpForwarderRequest {
4229
4379
 
4230
4380
  // Effective-path patterns that may be fetched without a session (GET/HEAD). A trailing \`/*\` matches descendants on segment boundaries (e.g. \`/icon/*\`). Used for PWA icons and similar public chrome; the manifest itself is allowed via \`Sec-Fetch-Dest: manifest\` and does not need to be listed.
4231
4381
  repeated string auth_public_paths = 18;
4382
+
4383
+ // The identity whose Volt hosts the target \`host\`/\`port\`, i.e. where requests matching this forwarder are tunnelled to. This allows a forwarder to be created on a public Volt (for a named host) while the target server runs on a different Volt that is relay-connected to it. When omitted, the creating identity is used.
4384
+ // The caller must be entitled to target the identity: it must either be the caller's own identity, the Volt handling this request, or an identity that has granted the caller \`volt:resource-write\`.
4385
+ string target_identity = 19;
4232
4386
  }
4233
4387
 
4234
4388
  message SaveHttpForwarderResponse {
@@ -4321,6 +4475,60 @@ message SaveHttpFileServerResponse {
4321
4475
  Resource resource = 2;
4322
4476
  }
4323
4477
 
4478
+ message PublishFolderRequest {
4479
+ // Optional name, extra user kinds, and attributes copied onto the local static file server (for example drive:publication-drive).
4480
+ // If \`id\` is set, this call updates the existing published-folder resource with that id; otherwise it creates a new published-folder resource. Updating keeps the loopback port the file server already listens on, and rotates the OIDC client id and secret when \`auth_enabled\` is set, which ends any sign-in sessions established against the previous pair.
4481
+ Resource resource = 1;
4482
+
4483
+ // Local filesystem path to publish. \`~\` is expanded. Must exist and be a directory.
4484
+ string path = 2;
4485
+
4486
+ // FQDN of the public Host to publish on (e.g. wiki.tdxid.com). This is also the HTTP forwarder's \`domain\`. Do not include a scheme or port. Must not be the publish Volt's own hostname. May be changed when updating, in which case the previous address is released.
4487
+ string domain = 3;
4488
+
4489
+ // DID of the relay Volt that owns the public domain. When omitted, the single connected \`volt:volt-link\` with \`volt:relay-exposed\` is used. If several such relays are connected, this field is required. If none are connected, the path is published on this Volt when HTTP forwarding is enabled.
4490
+ string relay_id = 4;
4491
+
4492
+ // When true, visitors must sign in via OIDC on the publish Volt and match an invitee access rule.
4493
+ bool auth_enabled = 5;
4494
+
4495
+ // Emails, email wildcards (e.g. "*@example.com"), or DIDs permitted through the published host when \`auth_enabled\` is set. At least one is required in that case.
4496
+ repeated string invitee = 6;
4497
+
4498
+ // When true, missing paths are rewritten to \`catch_all\` (SPA-style fallback). An empty \`catch_all\` responds with 404.
4499
+ bool catch_all_enabled = 7;
4500
+
4501
+ // Catch-all path, e.g. \`/index.html\` or \`/\`. Used when \`catch_all_enabled\` is set.
4502
+ string catch_all = 8;
4503
+ }
4504
+
4505
+ message PublishFolderResponse {
4506
+ // Details of any error that occurred on the call.
4507
+ tdx.volt_api.volt.v1.Status status = 1;
4508
+
4509
+ // The local static file server that represents the publication.
4510
+ Resource resource = 2;
4511
+
4512
+ // Public URL of the published folder.
4513
+ string url = 3;
4514
+
4515
+ // Resource id of the HTTP forwarder on the publish Volt.
4516
+ string forwarder_id = 4;
4517
+
4518
+ // Resource id of the OIDC client, when access is restricted.
4519
+ string oidc_client_id = 5;
4520
+ }
4521
+
4522
+ message UnpublishFolderRequest {
4523
+ // Resource id of the local file server created by PublishFolder. The resource must have kind \`volt:published-folder\`.
4524
+ string resource_id = 1;
4525
+ }
4526
+
4527
+ message UnpublishFolderResponse {
4528
+ // Details of any error that occurred on the call.
4529
+ tdx.volt_api.volt.v1.Status status = 1;
4530
+ }
4531
+
4324
4532
  message SaveHttpRestApiServerRequest {
4325
4533
  // Details of the resource to save.
4326
4534
  Resource resource = 1;
@@ -6797,6 +7005,10 @@ class VoltClient extends EventEmitter__default["default"] {
6797
7005
  return unaryCallInternal.call(this, "GetSessions", request);
6798
7006
  }
6799
7007
 
7008
+ PublishFolder(request) {
7009
+ return unaryCallInternal.call(this, "PublishFolder", request);
7010
+ }
7011
+
6800
7012
  SaveAccess(request) {
6801
7013
  return unaryCallInternal.call(this, "SaveAccess", request);
6802
7014
  }
@@ -6833,6 +7045,10 @@ class VoltClient extends EventEmitter__default["default"] {
6833
7045
  return unaryCallInternal.call(this, "SignVerify", request);
6834
7046
  }
6835
7047
 
7048
+ UnpublishFolder(request) {
7049
+ return unaryCallInternal.call(this, "UnpublishFolder", request);
7050
+ }
7051
+
6836
7052
  /**
6837
7053
  * VoltAPI - streaming (bidi). Use connect() for Connect stream.
6838
7054
  * Invoke is for relay proxying; returns a duplex stream of InvokeRequest/InvokeResponse.
@@ -7072,6 +7288,16 @@ class VoltClient extends EventEmitter__default["default"] {
7072
7288
  return unaryCallInternal.call(this, "SaveDriveInstance", request);
7073
7289
  }
7074
7290
 
7291
+ WatchDriveInstanceStatus(request) {
7292
+ const grpcClient = this.getVoltAPIClient();
7293
+ const watchDriveInstanceStatusCall = new GRPCCall(
7294
+ this,
7295
+ "WatchDriveInstanceStatus",
7296
+ "METHOD_TYPE_BIDI"
7297
+ );
7298
+ return watchDriveInstanceStatusCall.start(grpcClient, request);
7299
+ }
7300
+
7075
7301
  /**
7076
7302
  * SyncAPI
7077
7303
  */
@@ -7079,6 +7305,10 @@ class VoltClient extends EventEmitter__default["default"] {
7079
7305
  return unaryCallInternal.call(this, "CreateSynapseConnection", request);
7080
7306
  }
7081
7307
 
7308
+ CreateSyncDocumentVersion(request) {
7309
+ return unaryCallInternal.call(this, "CreateSyncDocumentVersion", request);
7310
+ }
7311
+
7082
7312
  DeleteSynapseConnection(request) {
7083
7313
  return unaryCallInternal.call(this, "DeleteSynapseConnection", request);
7084
7314
  }
@@ -7091,6 +7321,22 @@ class VoltClient extends EventEmitter__default["default"] {
7091
7321
  );
7092
7322
  }
7093
7323
 
7324
+ GetSynapseDocumentState(request) {
7325
+ return unaryCallInternal.call(this, "GetSynapseDocumentState", request);
7326
+ }
7327
+
7328
+ GetSyncDocumentVersion(request) {
7329
+ return unaryCallInternal.call(this, "GetSyncDocumentVersion", request);
7330
+ }
7331
+
7332
+ ListSyncDocumentVersions(request) {
7333
+ return unaryCallInternal.call(this, "ListSyncDocumentVersions", request);
7334
+ }
7335
+
7336
+ RevertSyncDocumentVersion(request) {
7337
+ return unaryCallInternal.call(this, "RevertSyncDocumentVersion", request);
7338
+ }
7339
+
7094
7340
  SaveSynapse(request) {
7095
7341
  return unaryCallInternal.call(this, "SaveSynapse", request);
7096
7342
  }
@@ -7114,6 +7360,16 @@ class VoltClient extends EventEmitter__default["default"] {
7114
7360
  return syncDocumentCall.start(grpcClient, request);
7115
7361
  }
7116
7362
 
7363
+ WatchSynapseDocumentState(request) {
7364
+ this.getVoltAPIClient();
7365
+
7366
+ new GRPCCall(
7367
+ this,
7368
+ "WatchSynapseDocumentState",
7369
+ "METHOD_TYPE_BIDI"
7370
+ );
7371
+ }
7372
+
7117
7373
  WatchSynapsePath(request) {
7118
7374
  const grpcClient = this.getVoltAPIClient();
7119
7375
 
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.20.31",
6
+ "version": "0.20.34",
7
7
  "description": "tdx Volt library for nodejs clients",
8
8
  "type": "module",
9
9
  "exports": {
@@ -33,8 +33,8 @@
33
33
  "author": "toby.ealden@gmail.com",
34
34
  "license": "ISC",
35
35
  "dependencies": {
36
- "@tdxvolt/volt-client-web": "^0.20.31",
37
- "@tdxvolt/volt-utility": "^0.20.31",
36
+ "@tdxvolt/volt-client-web": "^0.20.34",
37
+ "@tdxvolt/volt-utility": "^0.20.34",
38
38
  "debug": "^4.1.1",
39
39
  "ip": "^1.1.5",
40
40
  "jsonwebtoken": "^8.5.1",
@@ -455,6 +455,10 @@ export class VoltClient extends EventEmitter {
455
455
  return unaryCallInternal.call(this, "GetSessions", request);
456
456
  }
457
457
 
458
+ PublishFolder(request) {
459
+ return unaryCallInternal.call(this, "PublishFolder", request);
460
+ }
461
+
458
462
  SaveAccess(request) {
459
463
  return unaryCallInternal.call(this, "SaveAccess", request);
460
464
  }
@@ -491,6 +495,10 @@ export class VoltClient extends EventEmitter {
491
495
  return unaryCallInternal.call(this, "SignVerify", request);
492
496
  }
493
497
 
498
+ UnpublishFolder(request) {
499
+ return unaryCallInternal.call(this, "UnpublishFolder", request);
500
+ }
501
+
494
502
  /**
495
503
  * VoltAPI - streaming (bidi). Use connect() for Connect stream.
496
504
  * Invoke is for relay proxying; returns a duplex stream of InvokeRequest/InvokeResponse.
@@ -732,6 +740,16 @@ export class VoltClient extends EventEmitter {
732
740
  return unaryCallInternal.call(this, "SaveDriveInstance", request);
733
741
  }
734
742
 
743
+ WatchDriveInstanceStatus(request) {
744
+ const grpcClient = this.getVoltAPIClient();
745
+ const watchDriveInstanceStatusCall = new GRPCCall(
746
+ this,
747
+ "WatchDriveInstanceStatus",
748
+ "METHOD_TYPE_BIDI"
749
+ );
750
+ return watchDriveInstanceStatusCall.start(grpcClient, request);
751
+ }
752
+
735
753
  /**
736
754
  * SyncAPI
737
755
  */
@@ -739,6 +757,10 @@ export class VoltClient extends EventEmitter {
739
757
  return unaryCallInternal.call(this, "CreateSynapseConnection", request);
740
758
  }
741
759
 
760
+ CreateSyncDocumentVersion(request) {
761
+ return unaryCallInternal.call(this, "CreateSyncDocumentVersion", request);
762
+ }
763
+
742
764
  DeleteSynapseConnection(request) {
743
765
  return unaryCallInternal.call(this, "DeleteSynapseConnection", request);
744
766
  }
@@ -751,6 +773,22 @@ export class VoltClient extends EventEmitter {
751
773
  );
752
774
  }
753
775
 
776
+ GetSynapseDocumentState(request) {
777
+ return unaryCallInternal.call(this, "GetSynapseDocumentState", request);
778
+ }
779
+
780
+ GetSyncDocumentVersion(request) {
781
+ return unaryCallInternal.call(this, "GetSyncDocumentVersion", request);
782
+ }
783
+
784
+ ListSyncDocumentVersions(request) {
785
+ return unaryCallInternal.call(this, "ListSyncDocumentVersions", request);
786
+ }
787
+
788
+ RevertSyncDocumentVersion(request) {
789
+ return unaryCallInternal.call(this, "RevertSyncDocumentVersion", request);
790
+ }
791
+
754
792
  SaveSynapse(request) {
755
793
  return unaryCallInternal.call(this, "SaveSynapse", request);
756
794
  }
@@ -774,6 +812,16 @@ export class VoltClient extends EventEmitter {
774
812
  return syncDocumentCall.start(grpcClient, request);
775
813
  }
776
814
 
815
+ WatchSynapseDocumentState(request) {
816
+ const grpcClient = this.getVoltAPIClient();
817
+
818
+ const watchDocumentStateCall = new GRPCCall(
819
+ this,
820
+ "WatchSynapseDocumentState",
821
+ "METHOD_TYPE_BIDI"
822
+ );
823
+ }
824
+
777
825
  WatchSynapsePath(request) {
778
826
  const grpcClient = this.getVoltAPIClient();
779
827
 
@@ -495,9 +495,12 @@ import "tdx/volt_api/volt/v1/volt.proto";
495
495
 
496
496
  // The Drive API allows clients to create and manage Volt Drive resources.
497
497
  service DriveAPI {
498
- // Create or update a drive connection resource.
499
- // This is a privileged API call and requires volt:api-call / volt:save-drive-instance permission.
500
- rpc SaveDriveInstance(SaveDriveInstanceRequest) returns (SaveDriveInstanceResponse);
498
+ // Create or update a drive connection resource.
499
+ // This is a privileged API call and requires volt:api-call / volt:save-drive-instance permission.
500
+ rpc SaveDriveInstance(SaveDriveInstanceRequest) returns (SaveDriveInstanceResponse);
501
+
502
+ // Stream the FolderSync status of the drive instances on this Volt that host \`synapse_id\`. Busy means the local ingest/materialise queue is working. If there is no instance on this Volt, the stream reports absent.
503
+ rpc WatchDriveInstanceStatus(stream WatchDriveInstanceStatusRequest) returns (stream WatchDriveInstanceStatusResponse);
501
504
  }
502
505
 
503
506
  message SaveDriveInstanceRequest {
@@ -558,6 +561,47 @@ message SaveDriveInstanceResponse {
558
561
  Resource resource = 2;
559
562
  }
560
563
 
564
+ enum DriveInstanceState {
565
+ // No drive instance for this synapse is running on this Volt, so this Volt has nothing to say about its sync progress.
566
+ DRIVE_INSTANCE_STATE_ABSENT = 0;
567
+
568
+ // An instance is running with nothing queued.
569
+ DRIVE_INSTANCE_STATE_IDLE = 1;
570
+
571
+ // Files are queued, in flight, or the initial scan is running.
572
+ DRIVE_INSTANCE_STATE_BUSY = 2;
573
+ }
574
+
575
+ // FolderSync work on this Volt for a drive synapse.
576
+ message DriveInstanceStatus {
577
+ DriveInstanceState state = 1;
578
+
579
+ // Distinct files admitted to the operation currently underway, summed over every instance on this Volt that hosts the synapse. Grows as more work is discovered and never shrinks mid-operation. Zero once the drive settles.
580
+ uint32 total_count = 2;
581
+
582
+ // How many of \`total_count\` have reached a terminal state.
583
+ uint32 completed_count = 3;
584
+ }
585
+
586
+ message WatchDriveInstanceStatusStart {
587
+ // The id of the drive synapse (drive database) to watch.
588
+ string synapse_id = 1;
589
+ }
590
+
591
+ message WatchDriveInstanceStatusRequest {
592
+ oneof payload {
593
+ WatchDriveInstanceStatusStart start = 1;
594
+ bool stop = 2;
595
+ }
596
+ }
597
+
598
+ message WatchDriveInstanceStatusResponse {
599
+ oneof result {
600
+ tdx.volt_api.volt.v1.Status status = 1;
601
+ DriveInstanceStatus update = 2;
602
+ }
603
+ }
604
+
561
605
  `;
562
606
  export const file = `syntax = "proto3";
563
607
 
@@ -1222,6 +1266,12 @@ service SyncAPI {
1222
1266
  // Watch synapse paths for changes.
1223
1267
  rpc WatchSynapsePath(stream WatchSynapsePathRequest) returns (stream WatchSynapsePathResponse);
1224
1268
 
1269
+ // Get the state of a synapse document on this Volt. Reports whether the content this Volt holds matches the \`__hash\` advertised in the synapse metadata.
1270
+ rpc GetSynapseDocumentState(GetSynapseDocumentStateRequest) returns (GetSynapseDocumentStateResponse);
1271
+
1272
+ // Watch synapse documents for state changes. The server sends the current state of every watched document before any subsequent transitions, so a watcher started after content lands does not miss it.
1273
+ rpc WatchSynapseDocumentState(stream WatchSynapseDocumentStateRequest) returns (stream WatchSynapseDocumentStateResponse);
1274
+
1225
1275
  // Write a single value to a given synapse JSON path.
1226
1276
  rpc WriteSynapsePath(WriteSynapsePathRequest) returns (WriteSynapsePathResponse);
1227
1277
 
@@ -1432,8 +1482,8 @@ message SetSynapseDocumentMetadataRequest {
1432
1482
  // Any additional application-specific JSON to attach to the document.
1433
1483
  string json = 4;
1434
1484
 
1435
- // Set to true when the document content is already present (content-first) or the document is intentionally empty, so the server bootstraps \`__hash\` immediately. Leave false (the default) when content will be written after this call.
1436
- bool content_ready = 6;
1485
+ // Set to true to publish \`__hash\` immediately, because the content is already present (content-first) or the document is intentionally empty. Leave false (the default) when content will be written after this call, in which case the server publishes \`__hash\` once that content arrives. This is creator intent at create time; it says nothing about whether other Volts hold the content (see GetSynapseDocumentState).
1486
+ bool publish_hash = 6;
1437
1487
 
1438
1488
  // For blob documents, the content hash to bind. The server verifies the blob is stored (or the hash is sha256 of empty bytes) and writes \`__hash\`. Omit for a metadata-first create. Must not be set for map/array/text documents; the server computes those hashes from Yjs content.
1439
1489
  string blob_hash = 7;
@@ -1506,9 +1556,6 @@ message SyncDocumentResponse {
1506
1556
 
1507
1557
  // Parameters to start watching synapse paths. Sent as the first message.
1508
1558
  message WatchSynapsePathStart {
1509
- // DEPRECATED: Use synapse_id instead.
1510
- string database_id = 1;
1511
-
1512
1559
  // The id of the synapse that contains the document.
1513
1560
  string synapse_id = 4;
1514
1561
 
@@ -1669,16 +1716,100 @@ message RevertSyncDocumentVersionResponse {
1669
1716
  string version_id = 2;
1670
1717
  }
1671
1718
 
1719
+ // The state of a synapse document. \`__hash\` in the synapse metadata says what the content is; this says whether this Volt holds it yet. Metadata replicates independently of content, so a document can be ANNOUNCED here and READY on the Volt that produced it.
1720
+ enum SynapseDocumentState {
1721
+ SYNAPSE_DOCUMENT_STATE_UNKNOWN = 0;
1722
+
1723
+ // No metadata entry for this document on this Volt.
1724
+ SYNAPSE_DOCUMENT_STATE_ABSENT = 1;
1725
+
1726
+ // Metadata entry exists but no \`__hash\` has been published yet, so no content has been committed. See SetSynapseDocumentMetadata.publish_hash.
1727
+ SYNAPSE_DOCUMENT_STATE_DRAFT = 2;
1728
+
1729
+ // \`__hash\` is published but the content this Volt holds does not match it. The content is still in flight; wait for READY before reading it.
1730
+ SYNAPSE_DOCUMENT_STATE_ANNOUNCED = 3;
1731
+
1732
+ // The content this Volt holds matches \`__hash\`. The document can be read.
1733
+ SYNAPSE_DOCUMENT_STATE_READY = 4;
1734
+
1735
+ // The metadata entry was removed.
1736
+ SYNAPSE_DOCUMENT_STATE_DELETED = 5;
1737
+ }
1738
+
1739
+ message GetSynapseDocumentStateRequest {
1740
+ // The id of the synapse that contains the document.
1741
+ string synapse_id = 1;
1742
+
1743
+ // The id of the document to query.
1744
+ string document_id = 2;
1745
+ }
1746
+
1747
+ message GetSynapseDocumentStateResponse {
1748
+ // Details of any error that occurred on the call.
1749
+ tdx.volt_api.volt.v1.Status status = 1;
1750
+
1751
+ // The state of the document.
1752
+ SynapseDocumentState state = 2;
1753
+
1754
+ // The content hash advertised in the synapse metadata (\`__hash\`). Empty for ABSENT and DRAFT documents.
1755
+ string hash = 3;
1756
+
1757
+ // The content hash this Volt actually holds. Empty when no content has landed here yet. Equal to \`hash\` when the state is READY.
1758
+ string local_hash = 4;
1759
+ }
1760
+
1761
+ // Parameters to start watching synapse document state. Sent as the first message.
1762
+ message WatchSynapseDocumentStateStart {
1763
+ // The id of the synapse to watch.
1764
+ string synapse_id = 1;
1765
+
1766
+ // The ids of the documents to watch. Leave empty to watch every document in the synapse, including documents added after the watch starts.
1767
+ repeated string document_id = 2;
1768
+ }
1769
+
1770
+ message WatchSynapseDocumentStateRequest {
1771
+ oneof payload {
1772
+ // Start watching; must be sent as the first message.
1773
+ WatchSynapseDocumentStateStart start = 1;
1774
+
1775
+ // Request to stop the watch.
1776
+ bool stop = 2;
1777
+ }
1778
+ }
1779
+
1780
+ message WatchSynapseDocumentStateUpdate {
1781
+ // The id of the document whose state changed.
1782
+ string document_id = 1;
1783
+
1784
+ SynapseDocumentState state = 2;
1785
+
1786
+ // The content hash advertised in the synapse metadata (\`__hash\`).
1787
+ string hash = 3;
1788
+
1789
+ // The content hash this Volt actually holds.
1790
+ string local_hash = 4;
1791
+ }
1792
+
1793
+ message WatchSynapseDocumentStateResponse {
1794
+ oneof result {
1795
+ // Details of any error that occurred on the call.
1796
+ tdx.volt_api.volt.v1.Status status = 1;
1797
+
1798
+ // A document state update.
1799
+ WatchSynapseDocumentStateUpdate update = 2;
1800
+ }
1801
+ }
1802
+
1672
1803
  message HasSynapseBlobRequest {
1673
1804
  // The id of the synapse that stores the blob.
1674
1805
  string synapse_id = 1;
1675
1806
 
1676
- // sha256 of the raw file bytes, encoded as unpadded base64url (same family
1677
- // as VoltDrive content hashes).
1807
+ // SHA-256 of the raw file bytes, encoded as unpadded base64url.
1678
1808
  string hash = 2;
1679
1809
  }
1680
1810
 
1681
1811
  message HasSynapseBlobResponse {
1812
+ // Details of any error that occurred on the call.
1682
1813
  tdx.volt_api.volt.v1.Status status = 1;
1683
1814
 
1684
1815
  // True if a blob with this hash is already stored.
@@ -1686,6 +1817,7 @@ message HasSynapseBlobResponse {
1686
1817
  }
1687
1818
 
1688
1819
  message PutSynapseBlobStart {
1820
+ // The id of the synapse that stores the blob.
1689
1821
  string synapse_id = 1;
1690
1822
 
1691
1823
  // Expected sha256 (base64url) of the concatenated payload bytes.
@@ -1716,13 +1848,20 @@ message PutSynapseBlobResponse {
1716
1848
  }
1717
1849
 
1718
1850
  message GetSynapseBlobRequest {
1851
+ // The id of the synapse that stores the blob.
1719
1852
  string synapse_id = 1;
1853
+
1854
+ // SHA-256 of the raw file bytes, encoded as unpadded base64url.
1720
1855
  string hash = 2;
1721
1856
  }
1722
1857
 
1723
1858
  message GetSynapseBlobResponse {
1859
+ // The next chunk of blob data or details of any error that occurred on the call.
1724
1860
  oneof payload {
1861
+ // The next chunk of blob data.
1725
1862
  bytes block = 1;
1863
+
1864
+ // Details of any error that occurred on the call.
1726
1865
  tdx.volt_api.volt.v1.Status status = 2;
1727
1866
  }
1728
1867
  }
@@ -2100,6 +2239,9 @@ message VoltParameters {
2100
2239
 
2101
2240
  // Optional per-method gRPC rate limits (see GrpcRpcRateLimit). Keyed by peer identity or fingerprint.
2102
2241
  repeated GrpcRpcRateLimit grpc_rpc_rate_limit = 57;
2242
+
2243
+ // Deadline in milliseconds for outbound unary gRPC calls made by this Volt (relay, synapse, mirroring, drive and DID registry calls). If unset or zero, the built-in defaults are used.
2244
+ uint32 grpc_unary_deadline = 58;
2103
2245
  }
2104
2246
 
2105
2247
  message VoltEndpoint {
@@ -2636,6 +2778,14 @@ service VoltAPI {
2636
2778
  // This is a privileged API call and requires volt:api-call / volt:save-http-file-server permission.
2637
2779
  rpc SaveHttpFileServer(SaveHttpFileServerRequest) returns (SaveHttpFileServerResponse);
2638
2780
 
2781
+ // Publish a local filesystem folder over HTTP, optionally via a connected relay.
2782
+ // This is a privileged API call and requires volt:api-call / volt:publish-folder permission. Updating an existing publication additionally requires volt:resource-write on the published-folder resource.
2783
+ // On failure any resource this call created is removed, so a publication is never left half-built. Updates to an existing publication are idempotent: retry the same request to recover from a partial failure.
2784
+ rpc PublishFolder(PublishFolderRequest) returns (PublishFolderResponse);
2785
+
2786
+ // Remove a folder published by PublishFolder. Remote forwarder and OIDC resources are deleted first; the local file-server record is kept if remote cleanup fails so the operation can be retried. DeleteResource on a volt:published-folder resource performs the same remote cleanup.
2787
+ rpc UnpublishFolder(UnpublishFolderRequest) returns (UnpublishFolderResponse);
2788
+
2639
2789
  // Create or update an HTTP forwarder resource.
2640
2790
  // This is a privileged API call and requires volt:api-call / volt:save-http-forwarder permission.
2641
2791
  rpc SaveHttpForwarder(SaveHttpForwarderRequest) returns (SaveHttpForwarderResponse);
@@ -3640,7 +3790,7 @@ message SaveHttpForwarderRequest {
3640
3790
  // Set to indicate the resource attributes should be purged before saving the resource.
3641
3791
  bool purge_attributes = 4;
3642
3792
 
3643
- // The domain to forward requests to.
3793
+ // FQDN of the public Host this forwarder matches (e.g. wiki.tdxid.com). Do not include a scheme or port. Must not be this Volt's own hostname (use \`path\` for own-host forwarding). Optional when \`path\` is set.
3644
3794
  string domain = 5;
3645
3795
 
3646
3796
  // The host to forward requests to.
@@ -3652,7 +3802,7 @@ message SaveHttpForwarderRequest {
3652
3802
  // Set to indicate that the host header should reflect the proxy domain rather than the target host.
3653
3803
  bool forward_host = 8;
3654
3804
 
3655
- // Optional path prefix (e.g. "/myapp") for path-based forwarding. May be used on its own (path forwarding on the Volt's own host) or together with \`domain\` (sub-domain + path, e.g. sub.acme.com/myapp). At least one of \`domain\` or \`path\` must be set.
3805
+ // Optional path prefix (e.g. "/myapp") for path-based forwarding. May be used on its own (path forwarding on the Volt's own host) or together with \`domain\` (host + path, e.g. app.acme.com/myapp). At least one of \`domain\` or \`path\` must be set.
3656
3806
  string path = 9;
3657
3807
 
3658
3808
  // When a \`path\` prefix is configured, keep that prefix on the request path when forwarding. The default (false) is standard reverse-proxy behaviour: the prefix is stripped so the target receives the request at its own root (e.g. "/drive/assets/x.js" -> "/assets/x.js"), which suits plain static file servers and root-mounted backends. Set to true for targets that are themselves configured under the same sub-path and expect to receive the prefix. The \`X-Forwarded-Prefix\` header is always sent.
@@ -3661,7 +3811,7 @@ message SaveHttpForwarderRequest {
3661
3811
  // When true, incoming HTTP requests to this forwarder must carry a valid authenticated session (established via the OIDC sign-in flow) and pass the policy check before being proxied, except for the public-path and manifest exceptions on \`auth_public_paths\`. Unauthenticated top-level document navigations are redirected to the configured OpenID Provider; other unauthenticated requests receive 401. An authenticated session that fails the policy check receives 403. The Volt session cookie is stripped from the HTTP hop to the target. WebSocket and SSE upgrades are not gated.
3662
3812
  bool auth_enabled = 11;
3663
3813
 
3664
- // OpenID Provider issuer URL used for discovery (\`<issuer>/.well-known/openid-configuration\`). May be a Volt acting as an OpenID Provider, or any external OIDC provider. Required when \`auth_enabled\` is set.
3814
+ // OpenID Provider issuer URL used for discovery (\`[issuer]/.well-known/openid-configuration\`). May be a Volt acting as an OpenID Provider, or any external OIDC provider. Required when \`auth_enabled\` is set.
3665
3815
  string oidc_issuer = 12;
3666
3816
 
3667
3817
  // OAuth 2.0 client identifier registered with the OpenID Provider.
@@ -3681,6 +3831,10 @@ message SaveHttpForwarderRequest {
3681
3831
 
3682
3832
  // Effective-path patterns that may be fetched without a session (GET/HEAD). A trailing \`/*\` matches descendants on segment boundaries (e.g. \`/icon/*\`). Used for PWA icons and similar public chrome; the manifest itself is allowed via \`Sec-Fetch-Dest: manifest\` and does not need to be listed.
3683
3833
  repeated string auth_public_paths = 18;
3834
+
3835
+ // The identity whose Volt hosts the target \`host\`/\`port\`, i.e. where requests matching this forwarder are tunnelled to. This allows a forwarder to be created on a public Volt (for a named host) while the target server runs on a different Volt that is relay-connected to it. When omitted, the creating identity is used.
3836
+ // The caller must be entitled to target the identity: it must either be the caller's own identity, the Volt handling this request, or an identity that has granted the caller \`volt:resource-write\`.
3837
+ string target_identity = 19;
3684
3838
  }
3685
3839
 
3686
3840
  message SaveHttpForwarderResponse {
@@ -3773,6 +3927,60 @@ message SaveHttpFileServerResponse {
3773
3927
  Resource resource = 2;
3774
3928
  }
3775
3929
 
3930
+ message PublishFolderRequest {
3931
+ // Optional name, extra user kinds, and attributes copied onto the local static file server (for example drive:publication-drive).
3932
+ // If \`id\` is set, this call updates the existing published-folder resource with that id; otherwise it creates a new published-folder resource. Updating keeps the loopback port the file server already listens on, and rotates the OIDC client id and secret when \`auth_enabled\` is set, which ends any sign-in sessions established against the previous pair.
3933
+ Resource resource = 1;
3934
+
3935
+ // Local filesystem path to publish. \`~\` is expanded. Must exist and be a directory.
3936
+ string path = 2;
3937
+
3938
+ // FQDN of the public Host to publish on (e.g. wiki.tdxid.com). This is also the HTTP forwarder's \`domain\`. Do not include a scheme or port. Must not be the publish Volt's own hostname. May be changed when updating, in which case the previous address is released.
3939
+ string domain = 3;
3940
+
3941
+ // DID of the relay Volt that owns the public domain. When omitted, the single connected \`volt:volt-link\` with \`volt:relay-exposed\` is used. If several such relays are connected, this field is required. If none are connected, the path is published on this Volt when HTTP forwarding is enabled.
3942
+ string relay_id = 4;
3943
+
3944
+ // When true, visitors must sign in via OIDC on the publish Volt and match an invitee access rule.
3945
+ bool auth_enabled = 5;
3946
+
3947
+ // Emails, email wildcards (e.g. "*@example.com"), or DIDs permitted through the published host when \`auth_enabled\` is set. At least one is required in that case.
3948
+ repeated string invitee = 6;
3949
+
3950
+ // When true, missing paths are rewritten to \`catch_all\` (SPA-style fallback). An empty \`catch_all\` responds with 404.
3951
+ bool catch_all_enabled = 7;
3952
+
3953
+ // Catch-all path, e.g. \`/index.html\` or \`/\`. Used when \`catch_all_enabled\` is set.
3954
+ string catch_all = 8;
3955
+ }
3956
+
3957
+ message PublishFolderResponse {
3958
+ // Details of any error that occurred on the call.
3959
+ tdx.volt_api.volt.v1.Status status = 1;
3960
+
3961
+ // The local static file server that represents the publication.
3962
+ Resource resource = 2;
3963
+
3964
+ // Public URL of the published folder.
3965
+ string url = 3;
3966
+
3967
+ // Resource id of the HTTP forwarder on the publish Volt.
3968
+ string forwarder_id = 4;
3969
+
3970
+ // Resource id of the OIDC client, when access is restricted.
3971
+ string oidc_client_id = 5;
3972
+ }
3973
+
3974
+ message UnpublishFolderRequest {
3975
+ // Resource id of the local file server created by PublishFolder. The resource must have kind \`volt:published-folder\`.
3976
+ string resource_id = 1;
3977
+ }
3978
+
3979
+ message UnpublishFolderResponse {
3980
+ // Details of any error that occurred on the call.
3981
+ tdx.volt_api.volt.v1.Status status = 1;
3982
+ }
3983
+
3776
3984
  message SaveHttpRestApiServerRequest {
3777
3985
  // Details of the resource to save.
3778
3986
  Resource resource = 1;