From 17f589740967df6862a48ae4131c1986de97f154 Mon Sep 17 00:00:00 2001 From: Zhiqiang ZHOU Date: Sun, 26 Jul 2026 11:14:30 -0700 Subject: [PATCH 1/2] adopt AIP 151 operations --- Makefile | 1 + buf.gen.operations.yaml | 20 + buf.gen.yaml | 4 +- buf.lock | 6 + buf.yaml | 7 + ...protobuf-connect-api-with-aip-resources.md | 10 +- docs/web-app-plan.md | 4 +- frontend/src/api.ts | 23 +- frontend/src/gen/google/api/annotations_pb.ts | 38 ++ frontend/src/gen/google/api/client_pb.ts | 86 +++ .../src/gen/google/api/field_behavior_pb.ts | 156 +++++ frontend/src/gen/google/api/http_pb.ts | 436 +++++++++++++ frontend/src/gen/google/api/routing_pb.ts | 506 +++++++++++++++ frontend/src/gen/google/api/visibility_pb.ts | 83 +++ .../gen/google/longrunning/operations_pb.ts | 459 ++++++++++++++ frontend/src/gen/google/rpc/status_pb.ts | 75 +++ frontend/src/gen/lapp/web/v1/web_pb.ts | 138 ++-- frontend/src/store.ts | 5 +- .../operations.connect.go | 297 +++++++++ gen/go/lapp/web/v1/web.pb.go | 588 +++++++++--------- .../lapp/web/v1/webv1connect/web.connect.go | 25 +- go.mod | 4 +- pkg/webapp/import_service.go | 11 +- pkg/webapp/import_service_test.go | 70 ++- pkg/webapp/operations_service.go | 171 +++++ pkg/webapp/server.go | 3 + pkg/webapp/service.go | 12 +- pkg/webapp/service_test.go | 62 +- proto/lapp/web/v1/web.proto | 31 +- 29 files changed, 2910 insertions(+), 421 deletions(-) create mode 100644 buf.gen.operations.yaml create mode 100644 buf.lock create mode 100644 frontend/src/gen/google/api/annotations_pb.ts create mode 100644 frontend/src/gen/google/api/client_pb.ts create mode 100644 frontend/src/gen/google/api/field_behavior_pb.ts create mode 100644 frontend/src/gen/google/api/http_pb.ts create mode 100644 frontend/src/gen/google/api/routing_pb.ts create mode 100644 frontend/src/gen/google/api/visibility_pb.ts create mode 100644 frontend/src/gen/google/longrunning/operations_pb.ts create mode 100644 frontend/src/gen/google/rpc/status_pb.ts create mode 100644 gen/go/google/longrunning/longrunningpbconnect/operations.connect.go create mode 100644 pkg/webapp/operations_service.go diff --git a/Makefile b/Makefile index b63c8bf..484401c 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,7 @@ dev: clean build # Generate protobuf/Connect code proto-gen: buf generate + buf generate --template buf.gen.operations.yaml # Lint protobuf schemas proto-lint: diff --git a/buf.gen.operations.yaml b/buf.gen.operations.yaml new file mode 100644 index 0000000..dfa4d5a --- /dev/null +++ b/buf.gen.operations.yaml @@ -0,0 +1,20 @@ +version: v2 +plugins: + - remote: buf.build/connectrpc/go + out: gen/go + opt: + - paths=source_relative + types: + - google.longrunning.Operations + - remote: buf.build/bufbuild/es:v2.12.1 + out: frontend/src/gen + opt: + - target=ts + types: + - google.longrunning + - google.rpc.Status +inputs: + - module: buf.build/googleapis/googleapis + types: + - google.longrunning + - google.rpc.Status diff --git a/buf.gen.yaml b/buf.gen.yaml index 19aeb2b..c23022d 100644 --- a/buf.gen.yaml +++ b/buf.gen.yaml @@ -9,7 +9,9 @@ plugins: out: gen/go opt: - paths=source_relative - - remote: buf.build/bufbuild/es + types: + - lapp.web.v1.WorkspaceService + - remote: buf.build/bufbuild/es:v2.12.1 out: frontend/src/gen opt: - target=ts diff --git a/buf.lock b/buf.lock new file mode 100644 index 0000000..8447589 --- /dev/null +++ b/buf.lock @@ -0,0 +1,6 @@ +# Generated by buf. DO NOT EDIT. +version: v2 +deps: + - name: buf.build/googleapis/googleapis + commit: c17df5b2beca46928cc87d5656bd5343 + digest: b5:648a01e0170d4512dea7d564016165decd1ed6e34bef79fe54753e51ad7e27545709ad9157d7551270147d551155c595a2fb0bf5bb33b1c83040ddbce915c604 diff --git a/buf.yaml b/buf.yaml index c7e30e3..13ac200 100644 --- a/buf.yaml +++ b/buf.yaml @@ -1,9 +1,16 @@ version: v2 modules: - path: proto +deps: + - buf.build/googleapis/googleapis lint: use: - STANDARD + ignore_only: + RPC_REQUEST_RESPONSE_UNIQUE: + - proto/lapp/web/v1/web.proto + RPC_RESPONSE_STANDARD_NAME: + - proto/lapp/web/v1/web.proto breaking: use: - FILE diff --git a/docs/adr/0003-protobuf-connect-api-with-aip-resources.md b/docs/adr/0003-protobuf-connect-api-with-aip-resources.md index 17f7595..8940642 100644 --- a/docs/adr/0003-protobuf-connect-api-with-aip-resources.md +++ b/docs/adr/0003-protobuf-connect-api-with-aip-resources.md @@ -1,14 +1,14 @@ # Protobuf schema-first API with Connect and AIP resources -LAPP Web uses protobuf service definitions as the API contract, served through Connect RPC and consumed by generated Go and TypeScript code. API shapes should follow AIP resource-oriented design where it fits, while using custom methods for actions such as starting a discovery run that do not fit standard CRUD semantics. +LAPP Web uses protobuf service definitions as the API contract, served through Connect RPC and consumed by generated Go and TypeScript code. API shapes follow AIP resource design where it fits. Work that may take significant time follows AIP 151 and returns `google.longrunning.Operation`. -The first API resources use simple names: `Workspace`, `LogFile`, `DiscoveryRun`, and `Pattern`. Pattern resources belong to the discovery run that produced them. Pattern resource IDs use the generated `semantic_id`, which must be unique within a discovery run; duplicate semantic IDs are resolved with a numeric suffix. +The first API resources use simple names: `Workspace`, `LogFile`, `ImportRun`, `DiscoveryRun`, and `Pattern`. Pattern resources belong to the discovery run that produced them. Pattern resource IDs use the generated `semantic_id`, which must be unique within a discovery run; duplicate semantic IDs are resolved with a numeric suffix. -Discovery runs are started with `CreateDiscoveryRun`. Progress steps use user-facing stage names: reading logs, merging entries, discovering patterns, labeling patterns, and writing results. +Import and discovery runs are started with Create methods that return standard Operations. The operation metadata contains the run resource while work is active. A successful operation response contains the completed run resource. An execution failure is returned through `Operation.error`. Uploading or deleting log files does not automatically start discovery. Discovery is an explicit action and can be started whenever the user chooses. -Each workspace may have at most one running discovery run at a time because discovery writes generated workspace results. +Each workspace may have at most one running import or discovery operation at a time. A parallel Create request returns `ABORTED`. Log files cannot be uploaded or deleted while a discovery run is running for the same workspace. @@ -18,7 +18,7 @@ Discovery run history is retained so failures and prior runs can be inspected. T DiscoveryRun IDs use UUIDv7. Unlike Pattern IDs, DiscoveryRun IDs are operational record identifiers, not user-facing semantic handles. -The first version reports discovery progress through polling `GetDiscoveryRun`, not streaming. +Clients poll `google.longrunning.Operations.GetOperation` for standard operation state. `GetImportRun`, `ListImportRuns`, `GetDiscoveryRun`, and `ListDiscoveryRuns` remain available because runs are retained domain resources and history. Discovery results belong to the discovery run that produced them. Workspace views may present a selected discovery run's results instead of treating generated results as anonymous global workspace state. diff --git a/docs/web-app-plan.md b/docs/web-app-plan.md index 7f85c5a..f588477 100644 --- a/docs/web-app-plan.md +++ b/docs/web-app-plan.md @@ -7,9 +7,9 @@ LAPP Web is a local web app for working with local LAPP workspaces. It starts fr - Dashboard is a simple entry point for listing, creating, opening, and permanently deleting workspaces. - Workspace detail is the primary analysis surface. - Discovery is explicit. Uploading or deleting log files does not automatically start discovery. -- Discovery runs are asynchronous, one-time task executions. A completed run is not synchronized with later log file changes. +- Discovery runs are asynchronous, one time task executions. Create returns a standard long running Operation. A completed run is not synchronized with later log file changes. - Workspace views default to the latest successful discovery run. -- DiscoveryRun creation requires at least one log file and rejects concurrent runs for the same workspace at the API layer. +- DiscoveryRun creation requires at least one log file. A parallel run request returns `ABORTED`. - If the web server starts and finds local `QUEUED` or `RUNNING` DiscoveryRuns from a previous process, it marks them as failed because no worker is still attached to them. - Semantic labeling runs in batches of 25 patterns with default concurrency 12, a per-batch timeout, and up to 3 attempts per batch. - DiscoveryRun records store structured `progress` and `error` fields. Backend code records facts; frontend code renders user-facing text. diff --git a/frontend/src/api.ts b/frontend/src/api.ts index 208a8f0..102e8b3 100644 --- a/frontend/src/api.ts +++ b/frontend/src/api.ts @@ -1,10 +1,29 @@ +import { createRegistry } from "@bufbuild/protobuf"; import { createClient } from "@connectrpc/connect"; import { createConnectTransport } from "@connectrpc/connect-web"; -import { WorkspaceService } from "./gen/lapp/web/v1/web_pb"; +import { Operations } from "./gen/google/longrunning/operations_pb"; +import { + DiscoveryRunMetadataSchema, + DiscoveryRunSchema, + ImportRunMetadataSchema, + ImportRunSchema, + WorkspaceService +} from "./gen/lapp/web/v1/web_pb"; + +const typeRegistry = createRegistry( + DiscoveryRunMetadataSchema, + DiscoveryRunSchema, + ImportRunMetadataSchema, + ImportRunSchema +); const transport = createConnectTransport({ baseUrl: window.location.origin, - useBinaryFormat: false + useBinaryFormat: false, + jsonOptions: { + registry: typeRegistry + } }); export const workspaceClient = createClient(WorkspaceService, transport); +export const operationsClient = createClient(Operations, transport); diff --git a/frontend/src/gen/google/api/annotations_pb.ts b/frontend/src/gen/google/api/annotations_pb.ts new file mode 100644 index 0000000..1b7dc93 --- /dev/null +++ b/frontend/src/gen/google/api/annotations_pb.ts @@ -0,0 +1,38 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// @generated by protoc-gen-es v2.12.1 with parameter "target=ts" +// @generated from file google/api/annotations.proto (package google.api, syntax proto3) +/* eslint-disable */ + +import type { GenExtension, GenFile } from "@bufbuild/protobuf/codegenv2"; +import { extDesc, fileDesc } from "@bufbuild/protobuf/codegenv2"; +import type { HttpRule } from "./http_pb"; +import { file_google_api_http } from "./http_pb"; +import type { MethodOptions } from "@bufbuild/protobuf/wkt"; +import { file_google_protobuf_descriptor } from "@bufbuild/protobuf/wkt"; + +/** + * Describes the file google/api/annotations.proto. + */ +export const file_google_api_annotations: GenFile = /*@__PURE__*/ + fileDesc("Chxnb29nbGUvYXBpL2Fubm90YXRpb25zLnByb3RvEgpnb29nbGUuYXBpOksKBGh0dHASHi5nb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucxiwyrwiIAEoCzIULmdvb2dsZS5hcGkuSHR0cFJ1bGVSBGh0dHBCbgoOY29tLmdvb2dsZS5hcGlCEEFubm90YXRpb25zUHJvdG9QAVpBZ29vZ2xlLmdvbGFuZy5vcmcvZ2VucHJvdG8vZ29vZ2xlYXBpcy9hcGkvYW5ub3RhdGlvbnM7YW5ub3RhdGlvbnOiAgRHQVBJYgZwcm90bzM", [file_google_api_http, file_google_protobuf_descriptor]); + +/** + * See `HttpRule`. + * + * @generated from extension: google.api.HttpRule http = 72295728; + */ +export const http: GenExtension = /*@__PURE__*/ + extDesc(file_google_api_annotations, 0); diff --git a/frontend/src/gen/google/api/client_pb.ts b/frontend/src/gen/google/api/client_pb.ts new file mode 100644 index 0000000..5b7f8c7 --- /dev/null +++ b/frontend/src/gen/google/api/client_pb.ts @@ -0,0 +1,86 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// @generated by protoc-gen-es v2.12.1 with parameter "target=ts" +// @generated from file google/api/client.proto (package google.api, syntax proto3) +/* eslint-disable */ + +import type { GenExtension, GenFile } from "@bufbuild/protobuf/codegenv2"; +import { extDesc, fileDesc } from "@bufbuild/protobuf/codegenv2"; +import type { MethodOptions, ServiceOptions } from "@bufbuild/protobuf/wkt"; +import { file_google_protobuf_descriptor } from "@bufbuild/protobuf/wkt"; + +/** + * Describes the file google/api/client.proto. + */ +export const file_google_api_client: GenFile = /*@__PURE__*/ + fileDesc("Chdnb29nbGUvYXBpL2NsaWVudC5wcm90bxIKZ29vZ2xlLmFwaTpKChBtZXRob2Rfc2lnbmF0dXJlEh4uZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMYmwggAygJUg9tZXRob2RTaWduYXR1cmU6QwoMZGVmYXVsdF9ob3N0Eh8uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zGJkIIAEoCVILZGVmYXVsdEhvc3RCaQoOY29tLmdvb2dsZS5hcGlCC0NsaWVudFByb3RvUAFaQWdvb2dsZS5nb2xhbmcub3JnL2dlbnByb3RvL2dvb2dsZWFwaXMvYXBpL2Fubm90YXRpb25zO2Fubm90YXRpb25zogIER0FQSWIGcHJvdG8z", [file_google_protobuf_descriptor]); + +/** + * A definition of a client library method signature. + * + * In client libraries, each proto RPC corresponds to one or more methods + * which the end user is able to call, and calls the underlying RPC. + * Normally, this method receives a single argument (a struct or instance + * corresponding to the RPC request object). Defining this field will + * add one or more overloads providing flattened or simpler method signatures + * in some languages. + * + * The fields on the method signature are provided as a comma-separated + * string. + * + * For example, the proto RPC and annotation: + * + * rpc CreateSubscription(CreateSubscriptionRequest) + * returns (Subscription) { + * option (google.api.method_signature) = "name,topic"; + * } + * + * Would add the following Java overload (in addition to the method accepting + * the request object): + * + * public final Subscription createSubscription(String name, String topic) + * + * The following backwards-compatibility guidelines apply: + * + * * Adding this annotation to an unannotated method is backwards + * compatible. + * * Adding this annotation to a method which already has existing + * method signature annotations is backwards compatible if and only if + * the new method signature annotation is last in the sequence. + * * Modifying or removing an existing method signature annotation is + * a breaking change. + * * Re-ordering existing method signature annotations is a breaking + * change. + * + * @generated from extension: repeated string method_signature = 1051; + */ +export const method_signature: GenExtension = /*@__PURE__*/ + extDesc(file_google_api_client, 0); + +/** + * The hostname for this service. + * This should be specified with no prefix or protocol. + * + * Example: + * + * service Foo { + * option (google.api.default_host) = "foo.googleapi.com"; + * ... + * } + * + * @generated from extension: string default_host = 1049; + */ +export const default_host: GenExtension = /*@__PURE__*/ + extDesc(file_google_api_client, 1); diff --git a/frontend/src/gen/google/api/field_behavior_pb.ts b/frontend/src/gen/google/api/field_behavior_pb.ts new file mode 100644 index 0000000..df62c05 --- /dev/null +++ b/frontend/src/gen/google/api/field_behavior_pb.ts @@ -0,0 +1,156 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// @generated by protoc-gen-es v2.12.1 with parameter "target=ts" +// @generated from file google/api/field_behavior.proto (package google.api, syntax proto3) +/* eslint-disable */ + +import type { GenEnum, GenExtension, GenFile } from "@bufbuild/protobuf/codegenv2"; +import { enumDesc, extDesc, fileDesc } from "@bufbuild/protobuf/codegenv2"; +import type { FieldOptions } from "@bufbuild/protobuf/wkt"; +import { file_google_protobuf_descriptor } from "@bufbuild/protobuf/wkt"; + +/** + * Describes the file google/api/field_behavior.proto. + */ +export const file_google_api_field_behavior: GenFile = /*@__PURE__*/ + fileDesc("Ch9nb29nbGUvYXBpL2ZpZWxkX2JlaGF2aW9yLnByb3RvEgpnb29nbGUuYXBpKrYBCg1GaWVsZEJlaGF2aW9yEh4KGkZJRUxEX0JFSEFWSU9SX1VOU1BFQ0lGSUVEEAASDAoIT1BUSU9OQUwQARIMCghSRVFVSVJFRBACEg8KC09VVFBVVF9PTkxZEAMSDgoKSU5QVVRfT05MWRAEEg0KCUlNTVVUQUJMRRAFEhIKDlVOT1JERVJFRF9MSVNUEAYSFQoRTk9OX0VNUFRZX0RFRkFVTFQQBxIOCgpJREVOVElGSUVSEAg6ZAoOZmllbGRfYmVoYXZpb3ISHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGJwIIAMoDjIZLmdvb2dsZS5hcGkuRmllbGRCZWhhdmlvckICEABSDWZpZWxkQmVoYXZpb3JCcAoOY29tLmdvb2dsZS5hcGlCEkZpZWxkQmVoYXZpb3JQcm90b1ABWkFnb29nbGUuZ29sYW5nLm9yZy9nZW5wcm90by9nb29nbGVhcGlzL2FwaS9hbm5vdGF0aW9uczthbm5vdGF0aW9uc6ICBEdBUEliBnByb3RvMw", [file_google_protobuf_descriptor]); + +/** + * An indicator of the behavior of a given field (for example, that a field + * is required in requests, or given as output but ignored as input). + * This **does not** change the behavior in protocol buffers itself; it only + * denotes the behavior and may affect how API tooling handles the field. + * + * Note: This enum **may** receive new values in the future. + * + * @generated from enum google.api.FieldBehavior + */ +export enum FieldBehavior { + /** + * Conventional default for enums. Do not use this. + * + * @generated from enum value: FIELD_BEHAVIOR_UNSPECIFIED = 0; + */ + FIELD_BEHAVIOR_UNSPECIFIED = 0, + + /** + * Specifically denotes a field as optional. + * While all fields in protocol buffers are optional, this may be specified + * for emphasis if appropriate. + * + * @generated from enum value: OPTIONAL = 1; + */ + OPTIONAL = 1, + + /** + * Denotes a field as required. + * This indicates that the field **must** be provided as part of the request, + * and failure to do so will cause an error (usually `INVALID_ARGUMENT`). + * + * @generated from enum value: REQUIRED = 2; + */ + REQUIRED = 2, + + /** + * Denotes a field as output only. + * This indicates that the field is provided in responses, but including the + * field in a request does nothing (the server *must* ignore it and + * *must not* throw an error as a result of the field's presence). + * + * @generated from enum value: OUTPUT_ONLY = 3; + */ + OUTPUT_ONLY = 3, + + /** + * Denotes a field as input only. + * This indicates that the field is provided in requests, and the + * corresponding field is not included in output. + * + * @generated from enum value: INPUT_ONLY = 4; + */ + INPUT_ONLY = 4, + + /** + * Denotes a field as immutable. + * This indicates that the field may be set once in a request to create a + * resource, but may not be changed thereafter. + * + * @generated from enum value: IMMUTABLE = 5; + */ + IMMUTABLE = 5, + + /** + * Denotes that a (repeated) field is an unordered list. + * This indicates that the service may provide the elements of the list + * in any arbitrary order, rather than the order the user originally + * provided. Additionally, the list's order may or may not be stable. + * + * @generated from enum value: UNORDERED_LIST = 6; + */ + UNORDERED_LIST = 6, + + /** + * Denotes that this field returns a non-empty default value if not set. + * This indicates that if the user provides the empty value in a request, + * a non-empty value will be returned. The user will not be aware of what + * non-empty value to expect. + * + * @generated from enum value: NON_EMPTY_DEFAULT = 7; + */ + NON_EMPTY_DEFAULT = 7, + + /** + * Denotes that the field in a resource (a message annotated with + * google.api.resource) is used in the resource name to uniquely identify the + * resource. For AIP-compliant APIs, this should only be applied to the + * `name` field on the resource. + * + * This behavior should not be applied to references to other resources within + * the message. + * + * The identifier field of resources often have different field behavior + * depending on the request it is embedded in (e.g. for Create methods name + * is optional and unused, while for Update methods it is required). Instead + * of method-specific annotations, only `IDENTIFIER` is required. + * + * @generated from enum value: IDENTIFIER = 8; + */ + IDENTIFIER = 8, +} + +/** + * Describes the enum google.api.FieldBehavior. + */ +export const FieldBehaviorSchema: GenEnum = /*@__PURE__*/ + enumDesc(file_google_api_field_behavior, 0); + +/** + * A designation of a specific field behavior (required, output only, etc.) + * in protobuf messages. + * + * Examples: + * + * string name = 1 [(google.api.field_behavior) = REQUIRED]; + * State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY]; + * google.protobuf.Duration ttl = 1 + * [(google.api.field_behavior) = INPUT_ONLY]; + * google.protobuf.Timestamp expire_time = 1 + * [(google.api.field_behavior) = OUTPUT_ONLY, + * (google.api.field_behavior) = IMMUTABLE]; + * + * @generated from extension: repeated google.api.FieldBehavior field_behavior = 1052 [packed = false]; + */ +export const field_behavior: GenExtension = /*@__PURE__*/ + extDesc(file_google_api_field_behavior, 0); diff --git a/frontend/src/gen/google/api/http_pb.ts b/frontend/src/gen/google/api/http_pb.ts new file mode 100644 index 0000000..fcbcd83 --- /dev/null +++ b/frontend/src/gen/google/api/http_pb.ts @@ -0,0 +1,436 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// @generated by protoc-gen-es v2.12.1 with parameter "target=ts" +// @generated from file google/api/http.proto (package google.api, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/api/http.proto. + */ +export const file_google_api_http: GenFile = /*@__PURE__*/ + fileDesc("ChVnb29nbGUvYXBpL2h0dHAucHJvdG8SCmdvb2dsZS5hcGkigQIKCEh0dHBSdWxlEhAKCHNlbGVjdG9yGAEgASgJEg0KA2dldBgCIAEoCUgAEg0KA3B1dBgDIAEoCUgAEg4KBHBvc3QYBCABKAlIABIQCgZkZWxldGUYBSABKAlIABIPCgVwYXRjaBgGIAEoCUgAEi8KBmN1c3RvbRgIIAEoCzIdLmdvb2dsZS5hcGkuQ3VzdG9tSHR0cFBhdHRlcm5IABIMCgRib2R5GAcgASgJEhUKDXJlc3BvbnNlX2JvZHkYDCABKAkSMQoTYWRkaXRpb25hbF9iaW5kaW5ncxgLIAMoCzIULmdvb2dsZS5hcGkuSHR0cFJ1bGVCCQoHcGF0dGVybiIvChFDdXN0b21IdHRwUGF0dGVybhIMCgRraW5kGAEgASgJEgwKBHBhdGgYAiABKAlCZwoOY29tLmdvb2dsZS5hcGlCCUh0dHBQcm90b1ABWkFnb29nbGUuZ29sYW5nLm9yZy9nZW5wcm90by9nb29nbGVhcGlzL2FwaS9hbm5vdGF0aW9uczthbm5vdGF0aW9uc6ICBEdBUEliBnByb3RvMw"); + +/** + * gRPC Transcoding + * + * gRPC Transcoding is a feature for mapping between a gRPC method and one or + * more HTTP REST endpoints. It allows developers to build a single API service + * that supports both gRPC APIs and REST APIs. Many systems, including [Google + * APIs](https://github.com/googleapis/googleapis), + * [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC + * Gateway](https://github.com/grpc-ecosystem/grpc-gateway), + * and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature + * and use it for large scale production services. + * + * `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies + * how different portions of the gRPC request message are mapped to the URL + * path, URL query parameters, and HTTP request body. It also controls how the + * gRPC response message is mapped to the HTTP response body. `HttpRule` is + * typically specified as an `google.api.http` annotation on the gRPC method. + * + * Each mapping specifies a URL path template and an HTTP method. The path + * template may refer to one or more fields in the gRPC request message, as long + * as each field is a non-repeated field with a primitive (non-message) type. + * The path template controls how fields of the request message are mapped to + * the URL path. + * + * Example: + * + * service Messaging { + * rpc GetMessage(GetMessageRequest) returns (Message) { + * option (google.api.http) = { + * get: "/v1/{name=messages/*}" + * }; + * } + * } + * message GetMessageRequest { + * string name = 1; // Mapped to URL path. + * } + * message Message { + * string text = 1; // The resource content. + * } + * + * This enables an HTTP REST to gRPC mapping as below: + * + * - HTTP: `GET /v1/messages/123456` + * - gRPC: `GetMessage(name: "messages/123456")` + * + * Any fields in the request message which are not bound by the path template + * automatically become HTTP query parameters if there is no HTTP request body. + * For example: + * + * service Messaging { + * rpc GetMessage(GetMessageRequest) returns (Message) { + * option (google.api.http) = { + * get:"/v1/messages/{message_id}" + * }; + * } + * } + * message GetMessageRequest { + * message SubMessage { + * string subfield = 1; + * } + * string message_id = 1; // Mapped to URL path. + * int64 revision = 2; // Mapped to URL query parameter `revision`. + * SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`. + * } + * + * This enables a HTTP JSON to RPC mapping as below: + * + * - HTTP: `GET /v1/messages/123456?revision=2&sub.subfield=foo` + * - gRPC: `GetMessage(message_id: "123456" revision: 2 sub: + * SubMessage(subfield: "foo"))` + * + * Note that fields which are mapped to URL query parameters must have a + * primitive type or a repeated primitive type or a non-repeated message type. + * In the case of a repeated type, the parameter can be repeated in the URL + * as `...?param=A¶m=B`. In the case of a message type, each field of the + * message is mapped to a separate parameter, such as + * `...?foo.a=A&foo.b=B&foo.c=C`. + * + * For HTTP methods that allow a request body, the `body` field + * specifies the mapping. Consider a REST update method on the + * message resource collection: + * + * service Messaging { + * rpc UpdateMessage(UpdateMessageRequest) returns (Message) { + * option (google.api.http) = { + * patch: "/v1/messages/{message_id}" + * body: "message" + * }; + * } + * } + * message UpdateMessageRequest { + * string message_id = 1; // mapped to the URL + * Message message = 2; // mapped to the body + * } + * + * The following HTTP JSON to RPC mapping is enabled, where the + * representation of the JSON in the request body is determined by + * protos JSON encoding: + * + * - HTTP: `PATCH /v1/messages/123456 { "text": "Hi!" }` + * - gRPC: `UpdateMessage(message_id: "123456" message { text: "Hi!" })` + * + * The special name `*` can be used in the body mapping to define that + * every field not bound by the path template should be mapped to the + * request body. This enables the following alternative definition of + * the update method: + * + * service Messaging { + * rpc UpdateMessage(Message) returns (Message) { + * option (google.api.http) = { + * patch: "/v1/messages/{message_id}" + * body: "*" + * }; + * } + * } + * message Message { + * string message_id = 1; + * string text = 2; + * } + * + * + * The following HTTP JSON to RPC mapping is enabled: + * + * - HTTP: `PATCH /v1/messages/123456 { "text": "Hi!" }` + * - gRPC: `UpdateMessage(message_id: "123456" text: "Hi!")` + * + * Note that when using `*` in the body mapping, it is not possible to + * have HTTP parameters, as all fields not bound by the path end in + * the body. This makes this option more rarely used in practice when + * defining REST APIs. The common usage of `*` is in custom methods + * which don't use the URL at all for transferring data. + * + * It is possible to define multiple HTTP methods for one RPC by using + * the `additional_bindings` option. Example: + * + * service Messaging { + * rpc GetMessage(GetMessageRequest) returns (Message) { + * option (google.api.http) = { + * get: "/v1/messages/{message_id}" + * additional_bindings { + * get: "/v1/users/{user_id}/messages/{message_id}" + * } + * }; + * } + * } + * message GetMessageRequest { + * string message_id = 1; + * string user_id = 2; + * } + * + * This enables the following two alternative HTTP JSON to RPC mappings: + * + * - HTTP: `GET /v1/messages/123456` + * - gRPC: `GetMessage(message_id: "123456")` + * + * - HTTP: `GET /v1/users/me/messages/123456` + * - gRPC: `GetMessage(user_id: "me" message_id: "123456")` + * + * Rules for HTTP mapping + * + * 1. Leaf request fields (recursive expansion nested messages in the request + * message) are classified into three categories: + * - Fields referred by the path template. They are passed via the URL path. + * - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They + * are passed via the HTTP + * request body. + * - All other fields are passed via the URL query parameters, and the + * parameter name is the field path in the request message. A repeated + * field can be represented as multiple query parameters under the same + * name. + * 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL + * query parameter, all fields + * are passed via URL path and HTTP request body. + * 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP + * request body, all + * fields are passed via URL path and URL query parameters. + * + * Path template syntax + * + * Template = "/" Segments [ Verb ] ; + * Segments = Segment { "/" Segment } ; + * Segment = "*" | "**" | LITERAL | Variable ; + * Variable = "{" FieldPath [ "=" Segments ] "}" ; + * FieldPath = IDENT { "." IDENT } ; + * Verb = ":" LITERAL ; + * + * The syntax `*` matches a single URL path segment. The syntax `**` matches + * zero or more URL path segments, which must be the last part of the URL path + * except the `Verb`. + * + * The syntax `Variable` matches part of the URL path as specified by its + * template. A variable template must not contain other variables. If a variable + * matches a single path segment, its template may be omitted, e.g. `{var}` + * is equivalent to `{var=*}`. + * + * The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL` + * contains any reserved character, such characters should be percent-encoded + * before the matching. + * + * If a variable contains exactly one path segment, such as `"{var}"` or + * `"{var=*}"`, when such a variable is expanded into a URL path on the client + * side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The + * server side does the reverse decoding. Such variables show up in the + * [Discovery + * Document](https://developers.google.com/discovery/v1/reference/apis) as + * `{var}`. + * + * If a variable contains multiple path segments, such as `"{var=foo/*}"` + * or `"{var=**}"`, when such a variable is expanded into a URL path on the + * client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. + * The server side does the reverse decoding, except "%2F" and "%2f" are left + * unchanged. Such variables show up in the + * [Discovery + * Document](https://developers.google.com/discovery/v1/reference/apis) as + * `{+var}`. + * + * Using gRPC API Service Configuration + * + * gRPC API Service Configuration (service config) is a configuration language + * for configuring a gRPC service to become a user-facing product. The + * service config is simply the YAML representation of the `google.api.Service` + * proto message. + * + * As an alternative to annotating your proto file, you can configure gRPC + * transcoding in your service config YAML files. You do this by specifying a + * `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same + * effect as the proto annotation. This can be particularly useful if you + * have a proto that is reused in multiple services. Note that any transcoding + * specified in the service config will override any matching transcoding + * configuration in the proto. + * + * The following example selects a gRPC method and applies an `HttpRule` to it: + * + * http: + * rules: + * - selector: example.v1.Messaging.GetMessage + * get: /v1/messages/{message_id}/{sub.subfield} + * + * Special notes + * + * When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the + * proto to JSON conversion must follow the [proto3 + * specification](https://developers.google.com/protocol-buffers/docs/proto3#json). + * + * While the single segment variable follows the semantics of + * [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String + * Expansion, the multi segment variable **does not** follow RFC 6570 Section + * 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion + * does not expand special characters like `?` and `#`, which would lead + * to invalid URLs. As the result, gRPC Transcoding uses a custom encoding + * for multi segment variables. + * + * The path variables **must not** refer to any repeated or mapped field, + * because client libraries are not capable of handling such variable expansion. + * + * The path variables **must not** capture the leading "/" character. The reason + * is that the most common use case "{var}" does not capture the leading "/" + * character. For consistency, all path variables must share the same behavior. + * + * Repeated message fields must not be mapped to URL query parameters, because + * no client library can support such complicated mapping. + * + * If an API needs to use a JSON array for request or response body, it can map + * the request or response body to a repeated field. However, some gRPC + * Transcoding implementations may not support this feature. + * + * @generated from message google.api.HttpRule + */ +export type HttpRule = Message<"google.api.HttpRule"> & { + /** + * Selects a method to which this rule applies. + * + * Refer to [selector][google.api.DocumentationRule.selector] for syntax + * details. + * + * @generated from field: string selector = 1; + */ + selector: string; + + /** + * Determines the URL pattern is matched by this rules. This pattern can be + * used with any of the {get|put|post|delete|patch} methods. A custom method + * can be defined using the 'custom' field. + * + * @generated from oneof google.api.HttpRule.pattern + */ + pattern: { + /** + * Maps to HTTP GET. Used for listing and getting information about + * resources. + * + * @generated from field: string get = 2; + */ + value: string; + case: "get"; + } | { + /** + * Maps to HTTP PUT. Used for replacing a resource. + * + * @generated from field: string put = 3; + */ + value: string; + case: "put"; + } | { + /** + * Maps to HTTP POST. Used for creating a resource or performing an action. + * + * @generated from field: string post = 4; + */ + value: string; + case: "post"; + } | { + /** + * Maps to HTTP DELETE. Used for deleting a resource. + * + * @generated from field: string delete = 5; + */ + value: string; + case: "delete"; + } | { + /** + * Maps to HTTP PATCH. Used for updating a resource. + * + * @generated from field: string patch = 6; + */ + value: string; + case: "patch"; + } | { + /** + * The custom pattern is used for specifying an HTTP method that is not + * included in the `pattern` field, such as HEAD, or "*" to leave the + * HTTP method unspecified for this rule. The wild-card rule is useful + * for services that provide content to Web (HTML) clients. + * + * @generated from field: google.api.CustomHttpPattern custom = 8; + */ + value: CustomHttpPattern; + case: "custom"; + } | { case: undefined; value?: undefined }; + + /** + * The name of the request field whose value is mapped to the HTTP request + * body, or `*` for mapping all request fields not captured by the path + * pattern to the HTTP body, or omitted for not having any HTTP request body. + * + * NOTE: the referred field must be present at the top-level of the request + * message type. + * + * @generated from field: string body = 7; + */ + body: string; + + /** + * Optional. The name of the response field whose value is mapped to the HTTP + * response body. When omitted, the entire response message will be used + * as the HTTP response body. + * + * NOTE: The referred field must be present at the top-level of the response + * message type. + * + * @generated from field: string response_body = 12; + */ + responseBody: string; + + /** + * Additional HTTP bindings for the selector. Nested bindings must + * not contain an `additional_bindings` field themselves (that is, + * the nesting may only be one level deep). + * + * @generated from field: repeated google.api.HttpRule additional_bindings = 11; + */ + additionalBindings: HttpRule[]; +}; + +/** + * Describes the message google.api.HttpRule. + * Use `create(HttpRuleSchema)` to create a new message. + */ +export const HttpRuleSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_api_http, 0); + +/** + * A custom pattern is used for defining custom HTTP verb. + * + * @generated from message google.api.CustomHttpPattern + */ +export type CustomHttpPattern = Message<"google.api.CustomHttpPattern"> & { + /** + * The name of this custom HTTP verb. + * + * @generated from field: string kind = 1; + */ + kind: string; + + /** + * The path matched by this custom verb. + * + * @generated from field: string path = 2; + */ + path: string; +}; + +/** + * Describes the message google.api.CustomHttpPattern. + * Use `create(CustomHttpPatternSchema)` to create a new message. + */ +export const CustomHttpPatternSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_api_http, 1); diff --git a/frontend/src/gen/google/api/routing_pb.ts b/frontend/src/gen/google/api/routing_pb.ts new file mode 100644 index 0000000..0cf87b7 --- /dev/null +++ b/frontend/src/gen/google/api/routing_pb.ts @@ -0,0 +1,506 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// @generated by protoc-gen-es v2.12.1 with parameter "target=ts" +// @generated from file google/api/routing.proto (package google.api, syntax proto3) +/* eslint-disable */ + +import type { GenExtension, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2"; +import { extDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2"; +import type { MethodOptions } from "@bufbuild/protobuf/wkt"; +import { file_google_protobuf_descriptor } from "@bufbuild/protobuf/wkt"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/api/routing.proto. + */ +export const file_google_api_routing: GenFile = /*@__PURE__*/ + fileDesc("Chhnb29nbGUvYXBpL3JvdXRpbmcucHJvdG8SCmdvb2dsZS5hcGkiRwoLUm91dGluZ1J1bGUSOAoScm91dGluZ19wYXJhbWV0ZXJzGAIgAygLMhwuZ29vZ2xlLmFwaS5Sb3V0aW5nUGFyYW1ldGVyIjgKEFJvdXRpbmdQYXJhbWV0ZXISDQoFZmllbGQYASABKAkSFQoNcGF0aF90ZW1wbGF0ZRgCIAEoCTpUCgdyb3V0aW5nEh4uZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlvbnMYscq8IiABKAsyFy5nb29nbGUuYXBpLlJvdXRpbmdSdWxlUgdyb3V0aW5nQmoKDmNvbS5nb29nbGUuYXBpQgxSb3V0aW5nUHJvdG9QAVpBZ29vZ2xlLmdvbGFuZy5vcmcvZ2VucHJvdG8vZ29vZ2xlYXBpcy9hcGkvYW5ub3RhdGlvbnM7YW5ub3RhdGlvbnOiAgRHQVBJYgZwcm90bzM", [file_google_protobuf_descriptor]); + +/** + * Specifies the routing information that should be sent along with the request + * in the form of routing header. + * **NOTE:** All service configuration rules follow the "last one wins" order. + * + * The examples below will apply to an RPC which has the following request type: + * + * Message Definition: + * + * message Request { + * // The name of the Table + * // Values can be of the following formats: + * // - `projects//tables/` + * // - `projects//instances//tables/
` + * // - `region//zones//tables/
` + * string table_name = 1; + * + * // This value specifies routing for replication. + * // It can be in the following formats: + * // - `profiles/` + * // - a legacy `profile_id` that can be any string + * string app_profile_id = 2; + * } + * + * Example message: + * + * { + * table_name: projects/proj_foo/instances/instance_bar/table/table_baz, + * app_profile_id: profiles/prof_qux + * } + * + * The routing header consists of one or multiple key-value pairs. The order of + * the key-value pairs is undefined, the order of the `routing_parameters` in + * the `RoutingRule` only matters for the evaluation order of the path + * templates when `field` is the same. See the examples below for more details. + * + * Every key and value in the routing header must be percent-encoded, + * and joined together in the following format: `key1=value1&key2=value2`. + * The examples below skip the percent-encoding for readability. + * + * Example 1 + * + * Extracting a field from the request to put into the routing header + * unchanged, with the key equal to the field name. + * + * annotation: + * + * option (google.api.routing) = { + * // Take the `app_profile_id`. + * routing_parameters { + * field: "app_profile_id" + * } + * }; + * + * result: + * + * x-goog-request-params: app_profile_id=profiles/prof_qux + * + * Example 2 + * + * Extracting a field from the request to put into the routing header + * unchanged, with the key different from the field name. + * + * annotation: + * + * option (google.api.routing) = { + * // Take the `app_profile_id`, but name it `routing_id` in the header. + * routing_parameters { + * field: "app_profile_id" + * path_template: "{routing_id=**}" + * } + * }; + * + * result: + * + * x-goog-request-params: routing_id=profiles/prof_qux + * + * Example 3 + * + * Extracting a field from the request to put into the routing + * header, while matching a path template syntax on the field's value. + * + * NB: it is more useful to send nothing than to send garbage for the purpose + * of dynamic routing, since garbage pollutes cache. Thus the matching. + * + * Sub-example 3a + * + * The field matches the template. + * + * annotation: + * + * option (google.api.routing) = { + * // Take the `table_name`, if it's well-formed (with project-based + * // syntax). + * routing_parameters { + * field: "table_name" + * path_template: "{table_name=projects/*\/instances/*\/**}" + * } + * }; + * + * result: + * + * x-goog-request-params: + * table_name=projects/proj_foo/instances/instance_bar/table/table_baz + * + * Sub-example 3b + * + * The field does not match the template. + * + * annotation: + * + * option (google.api.routing) = { + * // Take the `table_name`, if it's well-formed (with region-based + * // syntax). + * routing_parameters { + * field: "table_name" + * path_template: "{table_name=regions/*\/zones/*\/**}" + * } + * }; + * + * result: + * + * + * + * Sub-example 3c + * + * Multiple alternative conflictingly named path templates are + * specified. The one that matches is used to construct the header. + * + * annotation: + * + * option (google.api.routing) = { + * // Take the `table_name`, if it's well-formed, whether + * // using the region- or projects-based syntax. + * + * routing_parameters { + * field: "table_name" + * path_template: "{table_name=regions/*\/zones/*\/**}" + * } + * routing_parameters { + * field: "table_name" + * path_template: "{table_name=projects/*\/instances/*\/**}" + * } + * }; + * + * result: + * + * x-goog-request-params: + * table_name=projects/proj_foo/instances/instance_bar/table/table_baz + * + * Example 4 + * + * Extracting a single routing header key-value pair by matching a + * template syntax on (a part of) a single request field. + * + * annotation: + * + * option (google.api.routing) = { + * // Take just the project id from the `table_name` field. + * routing_parameters { + * field: "table_name" + * path_template: "{routing_id=projects/*}/**" + * } + * }; + * + * result: + * + * x-goog-request-params: routing_id=projects/proj_foo + * + * Example 5 + * + * Extracting a single routing header key-value pair by matching + * several conflictingly named path templates on (parts of) a single request + * field. The last template to match "wins" the conflict. + * + * annotation: + * + * option (google.api.routing) = { + * // If the `table_name` does not have instances information, + * // take just the project id for routing. + * // Otherwise take project + instance. + * + * routing_parameters { + * field: "table_name" + * path_template: "{routing_id=projects/*}/**" + * } + * routing_parameters { + * field: "table_name" + * path_template: "{routing_id=projects/*\/instances/*}/**" + * } + * }; + * + * result: + * + * x-goog-request-params: + * routing_id=projects/proj_foo/instances/instance_bar + * + * Example 6 + * + * Extracting multiple routing header key-value pairs by matching + * several non-conflicting path templates on (parts of) a single request field. + * + * Sub-example 6a + * + * Make the templates strict, so that if the `table_name` does not + * have an instance information, nothing is sent. + * + * annotation: + * + * option (google.api.routing) = { + * // The routing code needs two keys instead of one composite + * // but works only for the tables with the "project-instance" name + * // syntax. + * + * routing_parameters { + * field: "table_name" + * path_template: "{project_id=projects/*}/instances/*\/**" + * } + * routing_parameters { + * field: "table_name" + * path_template: "projects/*\/{instance_id=instances/*}/**" + * } + * }; + * + * result: + * + * x-goog-request-params: + * project_id=projects/proj_foo&instance_id=instances/instance_bar + * + * Sub-example 6b + * + * Make the templates loose, so that if the `table_name` does not + * have an instance information, just the project id part is sent. + * + * annotation: + * + * option (google.api.routing) = { + * // The routing code wants two keys instead of one composite + * // but will work with just the `project_id` for tables without + * // an instance in the `table_name`. + * + * routing_parameters { + * field: "table_name" + * path_template: "{project_id=projects/*}/**" + * } + * routing_parameters { + * field: "table_name" + * path_template: "projects/*\/{instance_id=instances/*}/**" + * } + * }; + * + * result (is the same as 6a for our example message because it has the instance + * information): + * + * x-goog-request-params: + * project_id=projects/proj_foo&instance_id=instances/instance_bar + * + * Example 7 + * + * Extracting multiple routing header key-value pairs by matching + * several path templates on multiple request fields. + * + * NB: note that here there is no way to specify sending nothing if one of the + * fields does not match its template. E.g. if the `table_name` is in the wrong + * format, the `project_id` will not be sent, but the `routing_id` will be. + * The backend routing code has to be aware of that and be prepared to not + * receive a full complement of keys if it expects multiple. + * + * annotation: + * + * option (google.api.routing) = { + * // The routing needs both `project_id` and `routing_id` + * // (from the `app_profile_id` field) for routing. + * + * routing_parameters { + * field: "table_name" + * path_template: "{project_id=projects/*}/**" + * } + * routing_parameters { + * field: "app_profile_id" + * path_template: "{routing_id=**}" + * } + * }; + * + * result: + * + * x-goog-request-params: + * project_id=projects/proj_foo&routing_id=profiles/prof_qux + * + * Example 8 + * + * Extracting a single routing header key-value pair by matching + * several conflictingly named path templates on several request fields. The + * last template to match "wins" the conflict. + * + * annotation: + * + * option (google.api.routing) = { + * // The `routing_id` can be a project id or a region id depending on + * // the table name format, but only if the `app_profile_id` is not set. + * // If `app_profile_id` is set it should be used instead. + * + * routing_parameters { + * field: "table_name" + * path_template: "{routing_id=projects/*}/**" + * } + * routing_parameters { + * field: "table_name" + * path_template: "{routing_id=regions/*}/**" + * } + * routing_parameters { + * field: "app_profile_id" + * path_template: "{routing_id=**}" + * } + * }; + * + * result: + * + * x-goog-request-params: routing_id=profiles/prof_qux + * + * Example 9 + * + * Bringing it all together. + * + * annotation: + * + * option (google.api.routing) = { + * // For routing both `table_location` and a `routing_id` are needed. + * // + * // table_location can be either an instance id or a region+zone id. + * // + * // For `routing_id`, take the value of `app_profile_id` + * // - If it's in the format `profiles/`, send + * // just the `` part. + * // - If it's any other literal, send it as is. + * // If the `app_profile_id` is empty, and the `table_name` starts with + * // the project_id, send that instead. + * + * routing_parameters { + * field: "table_name" + * path_template: "projects/*\/{table_location=instances/*}/tables/*" + * } + * routing_parameters { + * field: "table_name" + * path_template: "{table_location=regions/*\/zones/*}/tables/*" + * } + * routing_parameters { + * field: "table_name" + * path_template: "{routing_id=projects/*}/**" + * } + * routing_parameters { + * field: "app_profile_id" + * path_template: "{routing_id=**}" + * } + * routing_parameters { + * field: "app_profile_id" + * path_template: "profiles/{routing_id=*}" + * } + * }; + * + * result: + * + * x-goog-request-params: + * table_location=instances/instance_bar&routing_id=prof_qux + * + * @generated from message google.api.RoutingRule + */ +export type RoutingRule = Message<"google.api.RoutingRule"> & { + /** + * A collection of Routing Parameter specifications. + * **NOTE:** If multiple Routing Parameters describe the same key + * (via the `path_template` field or via the `field` field when + * `path_template` is not provided), "last one wins" rule + * determines which Parameter gets used. + * See the examples for more details. + * + * @generated from field: repeated google.api.RoutingParameter routing_parameters = 2; + */ + routingParameters: RoutingParameter[]; +}; + +/** + * Describes the message google.api.RoutingRule. + * Use `create(RoutingRuleSchema)` to create a new message. + */ +export const RoutingRuleSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_api_routing, 0); + +/** + * A projection from an input message to the GRPC or REST header. + * + * @generated from message google.api.RoutingParameter + */ +export type RoutingParameter = Message<"google.api.RoutingParameter"> & { + /** + * A request field to extract the header key-value pair from. + * + * @generated from field: string field = 1; + */ + field: string; + + /** + * A pattern matching the key-value field. Optional. + * If not specified, the whole field specified in the `field` field will be + * taken as value, and its name used as key. If specified, it MUST contain + * exactly one named segment (along with any number of unnamed segments) The + * pattern will be matched over the field specified in the `field` field, then + * if the match is successful: + * - the name of the single named segment will be used as a header name, + * - the match value of the segment will be used as a header value; + * if the match is NOT successful, nothing will be sent. + * + * Example: + * + * -- This is a field in the request message + * | that the header value will be extracted from. + * | + * | -- This is the key name in the + * | | routing header. + * V | + * field: "table_name" v + * path_template: "projects/*\/{table_location=instances/*}/tables/*" + * ^ ^ + * | | + * In the {} brackets is the pattern that -- | + * specifies what to extract from the | + * field as a value to be sent. | + * | + * The string in the field must match the whole pattern -- + * before brackets, inside brackets, after brackets. + * + * When looking at this specific example, we can see that: + * - A key-value pair with the key `table_location` + * and the value matching `instances/*` should be added + * to the x-goog-request-params routing header. + * - The value is extracted from the request message's `table_name` field + * if it matches the full pattern specified: + * `projects/*\/instances/*\/tables/*`. + * + * **NB:** If the `path_template` field is not provided, the key name is + * equal to the field name, and the whole field should be sent as a value. + * This makes the pattern for the field and the value functionally equivalent + * to `**`, and the configuration + * + * { + * field: "table_name" + * } + * + * is a functionally equivalent shorthand to: + * + * { + * field: "table_name" + * path_template: "{table_name=**}" + * } + * + * See Example 1 for more details. + * + * @generated from field: string path_template = 2; + */ + pathTemplate: string; +}; + +/** + * Describes the message google.api.RoutingParameter. + * Use `create(RoutingParameterSchema)` to create a new message. + */ +export const RoutingParameterSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_api_routing, 1); + +/** + * See RoutingRule. + * + * @generated from extension: google.api.RoutingRule routing = 72295729; + */ +export const routing: GenExtension = /*@__PURE__*/ + extDesc(file_google_api_routing, 0); diff --git a/frontend/src/gen/google/api/visibility_pb.ts b/frontend/src/gen/google/api/visibility_pb.ts new file mode 100644 index 0000000..663b7b8 --- /dev/null +++ b/frontend/src/gen/google/api/visibility_pb.ts @@ -0,0 +1,83 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// @generated by protoc-gen-es v2.12.1 with parameter "target=ts" +// @generated from file google/api/visibility.proto (package google.api, syntax proto3) +/* eslint-disable */ + +import type { GenExtension, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2"; +import { extDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2"; +import type { MethodOptions } from "@bufbuild/protobuf/wkt"; +import { file_google_protobuf_descriptor } from "@bufbuild/protobuf/wkt"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/api/visibility.proto. + */ +export const file_google_api_visibility: GenFile = /*@__PURE__*/ + fileDesc("Chtnb29nbGUvYXBpL3Zpc2liaWxpdHkucHJvdG8SCmdvb2dsZS5hcGkiNwoOVmlzaWJpbGl0eVJ1bGUSEAoIc2VsZWN0b3IYASABKAkSEwoLcmVzdHJpY3Rpb24YAiABKAk6agoRbWV0aG9kX3Zpc2liaWxpdHkSHi5nb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucxivyrwiIAEoCzIaLmdvb2dsZS5hcGkuVmlzaWJpbGl0eVJ1bGVSEG1ldGhvZFZpc2liaWxpdHlCawoOY29tLmdvb2dsZS5hcGlCD1Zpc2liaWxpdHlQcm90b1ABWj9nb29nbGUuZ29sYW5nLm9yZy9nZW5wcm90by9nb29nbGVhcGlzL2FwaS92aXNpYmlsaXR5O3Zpc2liaWxpdHmiAgRHQVBJYgZwcm90bzM", [file_google_protobuf_descriptor]); + +/** + * A visibility rule provides visibility configuration for an individual API + * element. + * + * @generated from message google.api.VisibilityRule + */ +export type VisibilityRule = Message<"google.api.VisibilityRule"> & { + /** + * Selects methods, messages, fields, enums, etc. to which this rule applies. + * + * Refer to [selector][google.api.DocumentationRule.selector] for syntax + * details. + * + * @generated from field: string selector = 1; + */ + selector: string; + + /** + * A comma-separated list of visibility labels that apply to the `selector`. + * Any of the listed labels can be used to grant the visibility. + * + * If a rule has multiple labels, removing one of the labels but not all of + * them can break clients. + * + * Example: + * + * visibility: + * rules: + * - selector: google.calendar.Calendar.EnhancedSearch + * restriction: INTERNAL, PREVIEW + * + * Removing INTERNAL from this restriction will break clients that rely on + * this method and only had access to it through INTERNAL. + * + * @generated from field: string restriction = 2; + */ + restriction: string; +}; + +/** + * Describes the message google.api.VisibilityRule. + * Use `create(VisibilityRuleSchema)` to create a new message. + */ +export const VisibilityRuleSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_api_visibility, 0); + +/** + * See `VisibilityRule`. + * + * @generated from extension: google.api.VisibilityRule method_visibility = 72295727; + */ +export const method_visibility: GenExtension = /*@__PURE__*/ + extDesc(file_google_api_visibility, 0); diff --git a/frontend/src/gen/google/longrunning/operations_pb.ts b/frontend/src/gen/google/longrunning/operations_pb.ts new file mode 100644 index 0000000..f69a2b2 --- /dev/null +++ b/frontend/src/gen/google/longrunning/operations_pb.ts @@ -0,0 +1,459 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// @generated by protoc-gen-es v2.12.1 with parameter "target=ts" +// @generated from file google/longrunning/operations.proto (package google.longrunning, syntax proto3) +/* eslint-disable */ + +import type { GenExtension, GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2"; +import { extDesc, fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2"; +import { file_google_api_annotations } from "../api/annotations_pb"; +import { file_google_api_client } from "../api/client_pb"; +import { file_google_api_field_behavior } from "../api/field_behavior_pb"; +import type { Any, Duration, EmptySchema, MethodOptions } from "@bufbuild/protobuf/wkt"; +import { file_google_protobuf_any, file_google_protobuf_descriptor, file_google_protobuf_duration, file_google_protobuf_empty } from "@bufbuild/protobuf/wkt"; +import type { Status } from "../rpc/status_pb"; +import { file_google_rpc_status } from "../rpc/status_pb"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/longrunning/operations.proto. + */ +export const file_google_longrunning_operations: GenFile = /*@__PURE__*/ + fileDesc("CiNnb29nbGUvbG9uZ3J1bm5pbmcvb3BlcmF0aW9ucy5wcm90bxISZ29vZ2xlLmxvbmdydW5uaW5nIqgBCglPcGVyYXRpb24SDAoEbmFtZRgBIAEoCRImCghtZXRhZGF0YRgCIAEoCzIULmdvb2dsZS5wcm90b2J1Zi5BbnkSDAoEZG9uZRgDIAEoCBIjCgVlcnJvchgEIAEoCzISLmdvb2dsZS5ycGMuU3RhdHVzSAASKAoIcmVzcG9uc2UYBSABKAsyFC5nb29nbGUucHJvdG9idWYuQW55SABCCAoGcmVzdWx0IiMKE0dldE9wZXJhdGlvblJlcXVlc3QSDAoEbmFtZRgBIAEoCSJ8ChVMaXN0T3BlcmF0aW9uc1JlcXVlc3QSDAoEbmFtZRgEIAEoCRIOCgZmaWx0ZXIYASABKAkSEQoJcGFnZV9zaXplGAIgASgFEhIKCnBhZ2VfdG9rZW4YAyABKAkSHgoWcmV0dXJuX3BhcnRpYWxfc3VjY2VzcxgFIAEoCCJ+ChZMaXN0T3BlcmF0aW9uc1Jlc3BvbnNlEjEKCm9wZXJhdGlvbnMYASADKAsyHS5nb29nbGUubG9uZ3J1bm5pbmcuT3BlcmF0aW9uEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCRIYCgt1bnJlYWNoYWJsZRgDIAMoCUID4EEGIiYKFkNhbmNlbE9wZXJhdGlvblJlcXVlc3QSDAoEbmFtZRgBIAEoCSImChZEZWxldGVPcGVyYXRpb25SZXF1ZXN0EgwKBG5hbWUYASABKAkiUAoUV2FpdE9wZXJhdGlvblJlcXVlc3QSDAoEbmFtZRgBIAEoCRIqCgd0aW1lb3V0GAIgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uIj0KDU9wZXJhdGlvbkluZm8SFQoNcmVzcG9uc2VfdHlwZRgBIAEoCRIVCg1tZXRhZGF0YV90eXBlGAIgASgJMqgFCgpPcGVyYXRpb25zEpQBCg5MaXN0T3BlcmF0aW9ucxIpLmdvb2dsZS5sb25ncnVubmluZy5MaXN0T3BlcmF0aW9uc1JlcXVlc3QaKi5nb29nbGUubG9uZ3J1bm5pbmcuTGlzdE9wZXJhdGlvbnNSZXNwb25zZSIr2kELbmFtZSxmaWx0ZXKC0+STAhcSFS92MS97bmFtZT1vcGVyYXRpb25zfRJ/CgxHZXRPcGVyYXRpb24SJy5nb29nbGUubG9uZ3J1bm5pbmcuR2V0T3BlcmF0aW9uUmVxdWVzdBodLmdvb2dsZS5sb25ncnVubmluZy5PcGVyYXRpb24iJ9pBBG5hbWWC0+STAhoSGC92MS97bmFtZT1vcGVyYXRpb25zLyoqfRJ+Cg9EZWxldGVPcGVyYXRpb24SKi5nb29nbGUubG9uZ3J1bm5pbmcuRGVsZXRlT3BlcmF0aW9uUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIn2kEEbmFtZYLT5JMCGioYL3YxL3tuYW1lPW9wZXJhdGlvbnMvKip9EogBCg9DYW5jZWxPcGVyYXRpb24SKi5nb29nbGUubG9uZ3J1bm5pbmcuQ2FuY2VsT3BlcmF0aW9uUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIx2kEEbmFtZYLT5JMCJDoBKiIfL3YxL3tuYW1lPW9wZXJhdGlvbnMvKip9OmNhbmNlbBJYCg1XYWl0T3BlcmF0aW9uEiguZ29vZ2xlLmxvbmdydW5uaW5nLldhaXRPcGVyYXRpb25SZXF1ZXN0Gh0uZ29vZ2xlLmxvbmdydW5uaW5nLk9wZXJhdGlvbhodykEabG9uZ3J1bm5pbmcuZ29vZ2xlYXBpcy5jb206aQoOb3BlcmF0aW9uX2luZm8SHi5nb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucxiZCCABKAsyIS5nb29nbGUubG9uZ3J1bm5pbmcuT3BlcmF0aW9uSW5mb1INb3BlcmF0aW9uSW5mb0KiAQoWY29tLmdvb2dsZS5sb25ncnVubmluZ0IPT3BlcmF0aW9uc1Byb3RvUAFaQ2Nsb3VkLmdvb2dsZS5jb20vZ28vbG9uZ3J1bm5pbmcvYXV0b2dlbi9sb25ncnVubmluZ3BiO2xvbmdydW5uaW5ncGKiAgVHTFJVTqoCEkdvb2dsZS5Mb25nUnVubmluZ8oCEkdvb2dsZVxMb25nUnVubmluZ2IGcHJvdG8z", [file_google_api_annotations, file_google_api_client, file_google_api_field_behavior, file_google_protobuf_any, file_google_protobuf_descriptor, file_google_protobuf_duration, file_google_protobuf_empty, file_google_rpc_status]); + +/** + * This resource represents a long-running operation that is the result of a + * network API call. + * + * @generated from message google.longrunning.Operation + */ +export type Operation = Message<"google.longrunning.Operation"> & { + /** + * The server-assigned name, which is only unique within the same service that + * originally returns it. If you use the default HTTP mapping, the + * `name` should be a resource name ending with `operations/{unique_id}`. + * + * @generated from field: string name = 1; + */ + name: string; + + /** + * Service-specific metadata associated with the operation. It typically + * contains progress information and common metadata such as create time. + * Some services might not provide such metadata. Any method that returns a + * long-running operation should document the metadata type, if any. + * + * @generated from field: google.protobuf.Any metadata = 2; + */ + metadata?: Any | undefined; + + /** + * If the value is `false`, it means the operation is still in progress. + * If `true`, the operation is completed, and either `error` or `response` is + * available. + * + * @generated from field: bool done = 3; + */ + done: boolean; + + /** + * The operation result, which can be either an `error` or a valid `response`. + * If `done` == `false`, neither `error` nor `response` is set. + * If `done` == `true`, exactly one of `error` or `response` can be set. + * Some services might not provide the result. + * + * @generated from oneof google.longrunning.Operation.result + */ + result: { + /** + * The error result of the operation in case of failure or cancellation. + * + * @generated from field: google.rpc.Status error = 4; + */ + value: Status; + case: "error"; + } | { + /** + * The normal, successful response of the operation. If the original + * method returns no data on success, such as `Delete`, the response is + * `google.protobuf.Empty`. If the original method is standard + * `Get`/`Create`/`Update`, the response should be the resource. For other + * methods, the response should have the type `XxxResponse`, where `Xxx` + * is the original method name. For example, if the original method name + * is `TakeSnapshot()`, the inferred response type is + * `TakeSnapshotResponse`. + * + * @generated from field: google.protobuf.Any response = 5; + */ + value: Any; + case: "response"; + } | { case: undefined; value?: undefined }; +}; + +/** + * Describes the message google.longrunning.Operation. + * Use `create(OperationSchema)` to create a new message. + */ +export const OperationSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_longrunning_operations, 0); + +/** + * The request message for + * [Operations.GetOperation][google.longrunning.Operations.GetOperation]. + * + * @generated from message google.longrunning.GetOperationRequest + */ +export type GetOperationRequest = Message<"google.longrunning.GetOperationRequest"> & { + /** + * The name of the operation resource. + * + * @generated from field: string name = 1; + */ + name: string; +}; + +/** + * Describes the message google.longrunning.GetOperationRequest. + * Use `create(GetOperationRequestSchema)` to create a new message. + */ +export const GetOperationRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_longrunning_operations, 1); + +/** + * The request message for + * [Operations.ListOperations][google.longrunning.Operations.ListOperations]. + * + * @generated from message google.longrunning.ListOperationsRequest + */ +export type ListOperationsRequest = Message<"google.longrunning.ListOperationsRequest"> & { + /** + * The name of the operation's parent resource. + * + * @generated from field: string name = 4; + */ + name: string; + + /** + * The standard list filter. + * + * @generated from field: string filter = 1; + */ + filter: string; + + /** + * The standard list page size. + * + * @generated from field: int32 page_size = 2; + */ + pageSize: number; + + /** + * The standard list page token. + * + * @generated from field: string page_token = 3; + */ + pageToken: string; + + /** + * When set to `true`, operations that are reachable are returned as normal, + * and those that are unreachable are returned in the + * [ListOperationsResponse.unreachable] field. + * + * This can only be `true` when reading across collections e.g. when `parent` + * is set to `"projects/example/locations/-"`. + * + * This field is not by default supported and will result in an + * `UNIMPLEMENTED` error if set unless explicitly documented otherwise in + * service or product specific documentation. + * + * @generated from field: bool return_partial_success = 5; + */ + returnPartialSuccess: boolean; +}; + +/** + * Describes the message google.longrunning.ListOperationsRequest. + * Use `create(ListOperationsRequestSchema)` to create a new message. + */ +export const ListOperationsRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_longrunning_operations, 2); + +/** + * The response message for + * [Operations.ListOperations][google.longrunning.Operations.ListOperations]. + * + * @generated from message google.longrunning.ListOperationsResponse + */ +export type ListOperationsResponse = Message<"google.longrunning.ListOperationsResponse"> & { + /** + * A list of operations that matches the specified filter in the request. + * + * @generated from field: repeated google.longrunning.Operation operations = 1; + */ + operations: Operation[]; + + /** + * The standard List next-page token. + * + * @generated from field: string next_page_token = 2; + */ + nextPageToken: string; + + /** + * Unordered list. Unreachable resources. Populated when the request sets + * `ListOperationsRequest.return_partial_success` and reads across + * collections e.g. when attempting to list all resources across all supported + * locations. + * + * @generated from field: repeated string unreachable = 3; + */ + unreachable: string[]; +}; + +/** + * Describes the message google.longrunning.ListOperationsResponse. + * Use `create(ListOperationsResponseSchema)` to create a new message. + */ +export const ListOperationsResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_longrunning_operations, 3); + +/** + * The request message for + * [Operations.CancelOperation][google.longrunning.Operations.CancelOperation]. + * + * @generated from message google.longrunning.CancelOperationRequest + */ +export type CancelOperationRequest = Message<"google.longrunning.CancelOperationRequest"> & { + /** + * The name of the operation resource to be cancelled. + * + * @generated from field: string name = 1; + */ + name: string; +}; + +/** + * Describes the message google.longrunning.CancelOperationRequest. + * Use `create(CancelOperationRequestSchema)` to create a new message. + */ +export const CancelOperationRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_longrunning_operations, 4); + +/** + * The request message for + * [Operations.DeleteOperation][google.longrunning.Operations.DeleteOperation]. + * + * @generated from message google.longrunning.DeleteOperationRequest + */ +export type DeleteOperationRequest = Message<"google.longrunning.DeleteOperationRequest"> & { + /** + * The name of the operation resource to be deleted. + * + * @generated from field: string name = 1; + */ + name: string; +}; + +/** + * Describes the message google.longrunning.DeleteOperationRequest. + * Use `create(DeleteOperationRequestSchema)` to create a new message. + */ +export const DeleteOperationRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_longrunning_operations, 5); + +/** + * The request message for + * [Operations.WaitOperation][google.longrunning.Operations.WaitOperation]. + * + * @generated from message google.longrunning.WaitOperationRequest + */ +export type WaitOperationRequest = Message<"google.longrunning.WaitOperationRequest"> & { + /** + * The name of the operation resource to wait on. + * + * @generated from field: string name = 1; + */ + name: string; + + /** + * The maximum duration to wait before timing out. If left blank, the wait + * will be at most the time permitted by the underlying HTTP/RPC protocol. + * If RPC context deadline is also specified, the shorter one will be used. + * + * @generated from field: google.protobuf.Duration timeout = 2; + */ + timeout?: Duration | undefined; +}; + +/** + * Describes the message google.longrunning.WaitOperationRequest. + * Use `create(WaitOperationRequestSchema)` to create a new message. + */ +export const WaitOperationRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_longrunning_operations, 6); + +/** + * A message representing the message types used by a long-running operation. + * + * Example: + * + * rpc Export(ExportRequest) returns (google.longrunning.Operation) { + * option (google.longrunning.operation_info) = { + * response_type: "ExportResponse" + * metadata_type: "ExportMetadata" + * }; + * } + * + * @generated from message google.longrunning.OperationInfo + */ +export type OperationInfo = Message<"google.longrunning.OperationInfo"> & { + /** + * Required. The message name of the primary return type for this + * long-running operation. + * This type will be used to deserialize the LRO's response. + * + * If the response is in a different package from the rpc, a fully-qualified + * message name must be used (e.g. `google.protobuf.Struct`). + * + * Note: Altering this value constitutes a breaking change. + * + * @generated from field: string response_type = 1; + */ + responseType: string; + + /** + * Required. The message name of the metadata type for this long-running + * operation. + * + * If the response is in a different package from the rpc, a fully-qualified + * message name must be used (e.g. `google.protobuf.Struct`). + * + * Note: Altering this value constitutes a breaking change. + * + * @generated from field: string metadata_type = 2; + */ + metadataType: string; +}; + +/** + * Describes the message google.longrunning.OperationInfo. + * Use `create(OperationInfoSchema)` to create a new message. + */ +export const OperationInfoSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_longrunning_operations, 7); + +/** + * Manages long-running operations with an API service. + * + * When an API method normally takes long time to complete, it can be designed + * to return [Operation][google.longrunning.Operation] to the client, and the + * client can use this interface to receive the real response asynchronously by + * polling the operation resource, or pass the operation resource to another API + * (such as Pub/Sub API) to receive the response. Any API service that returns + * long-running operations should implement the `Operations` interface so + * developers can have a consistent client experience. + * + * @generated from service google.longrunning.Operations + */ +export const Operations: GenService<{ + /** + * Lists operations that match the specified filter in the request. If the + * server doesn't support this method, it returns `UNIMPLEMENTED`. + * + * @generated from rpc google.longrunning.Operations.ListOperations + */ + listOperations: { + methodKind: "unary"; + input: typeof ListOperationsRequestSchema; + output: typeof ListOperationsResponseSchema; + }, + /** + * Gets the latest state of a long-running operation. Clients can use this + * method to poll the operation result at intervals as recommended by the API + * service. + * + * @generated from rpc google.longrunning.Operations.GetOperation + */ + getOperation: { + methodKind: "unary"; + input: typeof GetOperationRequestSchema; + output: typeof OperationSchema; + }, + /** + * Deletes a long-running operation. This method indicates that the client is + * no longer interested in the operation result. It does not cancel the + * operation. If the server doesn't support this method, it returns + * `google.rpc.Code.UNIMPLEMENTED`. + * + * @generated from rpc google.longrunning.Operations.DeleteOperation + */ + deleteOperation: { + methodKind: "unary"; + input: typeof DeleteOperationRequestSchema; + output: typeof EmptySchema; + }, + /** + * Starts asynchronous cancellation on a long-running operation. The server + * makes a best effort to cancel the operation, but success is not + * guaranteed. If the server doesn't support this method, it returns + * `google.rpc.Code.UNIMPLEMENTED`. Clients can use + * [Operations.GetOperation][google.longrunning.Operations.GetOperation] or + * other methods to check whether the cancellation succeeded or whether the + * operation completed despite cancellation. On successful cancellation, + * the operation is not deleted; instead, it becomes an operation with + * an [Operation.error][google.longrunning.Operation.error] value with a + * [google.rpc.Status.code][google.rpc.Status.code] of `1`, corresponding to + * `Code.CANCELLED`. + * + * @generated from rpc google.longrunning.Operations.CancelOperation + */ + cancelOperation: { + methodKind: "unary"; + input: typeof CancelOperationRequestSchema; + output: typeof EmptySchema; + }, + /** + * Waits until the specified long-running operation is done or reaches at most + * a specified timeout, returning the latest state. If the operation is + * already done, the latest state is immediately returned. If the timeout + * specified is greater than the default HTTP/RPC timeout, the HTTP/RPC + * timeout is used. If the server does not support this method, it returns + * `google.rpc.Code.UNIMPLEMENTED`. + * Note that this method is on a best-effort basis. It may return the latest + * state before the specified timeout (including immediately), meaning even an + * immediate response is no guarantee that the operation is done. + * + * @generated from rpc google.longrunning.Operations.WaitOperation + */ + waitOperation: { + methodKind: "unary"; + input: typeof WaitOperationRequestSchema; + output: typeof OperationSchema; + }, +}> = /*@__PURE__*/ + serviceDesc(file_google_longrunning_operations, 0); + +/** + * Additional information regarding long-running operations. + * In particular, this specifies the types that are returned from + * long-running operations. + * + * Required for methods that return `google.longrunning.Operation`; invalid + * otherwise. + * + * @generated from extension: google.longrunning.OperationInfo operation_info = 1049; + */ +export const operation_info: GenExtension = /*@__PURE__*/ + extDesc(file_google_longrunning_operations, 0); diff --git a/frontend/src/gen/google/rpc/status_pb.ts b/frontend/src/gen/google/rpc/status_pb.ts new file mode 100644 index 0000000..5ac2985 --- /dev/null +++ b/frontend/src/gen/google/rpc/status_pb.ts @@ -0,0 +1,75 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// @generated by protoc-gen-es v2.12.1 with parameter "target=ts" +// @generated from file google/rpc/status.proto (package google.rpc, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2"; +import type { Any } from "@bufbuild/protobuf/wkt"; +import { file_google_protobuf_any } from "@bufbuild/protobuf/wkt"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/rpc/status.proto. + */ +export const file_google_rpc_status: GenFile = /*@__PURE__*/ + fileDesc("Chdnb29nbGUvcnBjL3N0YXR1cy5wcm90bxIKZ29vZ2xlLnJwYyJOCgZTdGF0dXMSDAoEY29kZRgBIAEoBRIPCgdtZXNzYWdlGAIgASgJEiUKB2RldGFpbHMYAyADKAsyFC5nb29nbGUucHJvdG9idWYuQW55Ql4KDmNvbS5nb29nbGUucnBjQgtTdGF0dXNQcm90b1ABWjdnb29nbGUuZ29sYW5nLm9yZy9nZW5wcm90by9nb29nbGVhcGlzL3JwYy9zdGF0dXM7c3RhdHVzogIDUlBDYgZwcm90bzM", [file_google_protobuf_any]); + +/** + * The `Status` type defines a logical error model that is suitable for + * different programming environments, including REST APIs and RPC APIs. It is + * used by [gRPC](https://github.com/grpc). Each `Status` message contains + * three pieces of data: error code, error message, and error details. + * + * You can find out more about this error model and how to work with it in the + * [API Design Guide](https://cloud.google.com/apis/design/errors). + * + * @generated from message google.rpc.Status + */ +export type Status = Message<"google.rpc.Status"> & { + /** + * The status code, which should be an enum value of + * [google.rpc.Code][google.rpc.Code]. + * + * @generated from field: int32 code = 1; + */ + code: number; + + /** + * A developer-facing error message, which should be in English. Any + * user-facing error message should be localized and sent in the + * [google.rpc.Status.details][google.rpc.Status.details] field, or localized + * by the client. + * + * @generated from field: string message = 2; + */ + message: string; + + /** + * A list of messages that carry the error details. There is a common set of + * message types for APIs to use. + * + * @generated from field: repeated google.protobuf.Any details = 3; + */ + details: Any[]; +}; + +/** + * Describes the message google.rpc.Status. + * Use `create(StatusSchema)` to create a new message. + */ +export const StatusSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_rpc_status, 0); diff --git a/frontend/src/gen/lapp/web/v1/web_pb.ts b/frontend/src/gen/lapp/web/v1/web_pb.ts index 6b04e20..b7d45dd 100644 --- a/frontend/src/gen/lapp/web/v1/web_pb.ts +++ b/frontend/src/gen/lapp/web/v1/web_pb.ts @@ -4,6 +4,8 @@ import type { GenEnum, GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2"; import { enumDesc, fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2"; +import type { OperationSchema } from "../../../google/longrunning/operations_pb"; +import { file_google_longrunning_operations } from "../../../google/longrunning/operations_pb"; import type { Timestamp } from "@bufbuild/protobuf/wkt"; import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt"; import type { Message } from "@bufbuild/protobuf"; @@ -12,7 +14,7 @@ import type { Message } from "@bufbuild/protobuf"; * Describes the file lapp/web/v1/web.proto. */ export const file_lapp_web_v1_web: GenFile = /*@__PURE__*/ - fileDesc("ChVsYXBwL3dlYi92MS93ZWIucHJvdG8SC2xhcHAud2ViLnYxIokCCglXb3Jrc3BhY2USDAoEbmFtZRgBIAEoCRIUCgx3b3Jrc3BhY2VfaWQYAiABKAkSLAoGc3RhdHVzGAMgASgOMhwubGFwcC53ZWIudjEuV29ya3NwYWNlU3RhdHVzEhYKDmxvZ19maWxlX2NvdW50GAQgASgFEhUKDXBhdHRlcm5fY291bnQYBSABKAUSNwoUbGF0ZXN0X2Rpc2NvdmVyeV9ydW4YBiABKAsyGS5sYXBwLndlYi52MS5EaXNjb3ZlcnlSdW4SQgofbGF0ZXN0X3N1Y2Nlc3NmdWxfZGlzY292ZXJ5X3J1bhgHIAEoCzIZLmxhcHAud2ViLnYxLkRpc2NvdmVyeVJ1biJuCgdMb2dGaWxlEgwKBG5hbWUYASABKAkSEQoJZmlsZV9uYW1lGAIgASgJEhIKCnNpemVfYnl0ZXMYAyABKAMSLgoKdXBkYXRlZF9hdBgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAivAMKCUltcG9ydFJ1bhIMCgRuYW1lGAEgASgJEhUKDWltcG9ydF9ydW5faWQYAiABKAkSEAoIcHJvdmlkZXIYAyABKAkSDwoHcHJvamVjdBgEIAEoCRIOCgZmaWx0ZXIYBSABKAkSKAoEZnJvbRgGIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASJgoCdG8YByABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEg0KBWxpbWl0GAggASgFEioKBXN0YXRlGAkgASgOMhsubGFwcC53ZWIudjEuSW1wb3J0UnVuU3RhdGUSEwoLZW50cnlfY291bnQYCiABKAUSEQoJdHJ1bmNhdGVkGAsgASgIEhUKDWxvZ19maWxlX25hbWUYDCABKAkSLgoKc3RhcnRlZF9hdBgNIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLwoLZmluaXNoZWRfYXQYDiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEioKBWVycm9yGA8gASgLMhsubGFwcC53ZWIudjEuSW1wb3J0UnVuRXJyb3IiLwoOSW1wb3J0UnVuRXJyb3ISDAoEY29kZRgBIAEoCRIPCgdtZXNzYWdlGAIgASgJIt0DCgxEaXNjb3ZlcnlSdW4SDAoEbmFtZRgBIAEoCRIYChBkaXNjb3ZlcnlfcnVuX2lkGAIgASgJEi0KBXN0YXRlGAMgASgOMh4ubGFwcC53ZWIudjEuRGlzY292ZXJ5UnVuU3RhdGUSMAoMY3VycmVudF9zdGVwGAQgASgOMhoubGFwcC53ZWIudjEuRGlzY292ZXJ5U3RlcBIcChBwcm9ncmVzc19tZXNzYWdlGAUgASgJQgIYARIZCg1lcnJvcl9tZXNzYWdlGAYgASgJQgIYARIuCgpzdGFydGVkX2F0GAcgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIvCgtmaW5pc2hlZF9hdBgIIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASFgoObG9nX2ZpbGVfY291bnQYCSABKAUSFQoNcGF0dGVybl9jb3VudBgKIAEoBRIXCg91bm1hdGNoZWRfY291bnQYCyABKAUSMwoIcHJvZ3Jlc3MYDCABKAsyIS5sYXBwLndlYi52MS5EaXNjb3ZlcnlSdW5Qcm9ncmVzcxItCgVlcnJvchgNIAEoCzIeLmxhcHAud2ViLnYxLkRpc2NvdmVyeVJ1bkVycm9yIn8KFERpc2NvdmVyeVJ1blByb2dyZXNzEigKBHN0ZXAYASABKA4yGi5sYXBwLndlYi52MS5EaXNjb3ZlcnlTdGVwEj0KC2xhYmVsX2JhdGNoGAIgASgLMigubGFwcC53ZWIudjEuRGlzY292ZXJ5TGFiZWxCYXRjaFByb2dyZXNzIqsBChtEaXNjb3ZlcnlMYWJlbEJhdGNoUHJvZ3Jlc3MSDQoFZXZlbnQYASABKAkSFAoMYmF0Y2hfbnVtYmVyGAIgASgFEhMKC2JhdGNoX2NvdW50GAMgASgFEhIKCmJhdGNoX3NpemUYBCABKAUSDwoHYXR0ZW1wdBgFIAEoBRIUCgxtYXhfYXR0ZW1wdHMYBiABKAUSFwoPY29tcGxldGVkX2NvdW50GAcgASgFIlwKEURpc2NvdmVyeVJ1bkVycm9yEgwKBGNvZGUYASABKAkSDwoHbWVzc2FnZRgCIAEoCRIoCgRzdGVwGAMgASgOMhoubGFwcC53ZWIudjEuRGlzY292ZXJ5U3RlcCKDAgoHUGF0dGVybhIMCgRuYW1lGAEgASgJEhIKCnBhdHRlcm5faWQYAiABKAkSEwoLc2VtYW50aWNfaWQYAyABKAkSEwoLZGVzY3JpcHRpb24YBCABKAkSEAoIdGVtcGxhdGUYBSABKAkSDQoFY291bnQYBiABKAUSKAoKZmlyc3Rfc2VlbhgHIAEoCzIULmxhcHAud2ViLnYxLkxpbmVSZWYSJwoJbGFzdF9zZWVuGAggASgLMhQubGFwcC53ZWIudjEuTGluZVJlZhInCglsaW5lX3JlZnMYCSADKAsyFC5sYXBwLndlYi52MS5MaW5lUmVmEg8KB3NhbXBsZXMYCiADKAkiMQoHTGluZVJlZhIRCglmaWxlX25hbWUYASABKAkSEwoLbGluZV9udW1iZXIYAiABKAUiNQoMRXJyb3JQYXR0ZXJuEiUKB3BhdHRlcm4YASABKAsyFC5sYXBwLndlYi52MS5QYXR0ZXJuIk0KElVubWF0Y2hlZEVycm9yTGluZRIRCglmaWxlX25hbWUYASABKAkSEwoLbGluZV9udW1iZXIYAiABKAUSDwoHY29udGVudBgDIAEoCSIXChVMaXN0V29ya3NwYWNlc1JlcXVlc3QiRAoWTGlzdFdvcmtzcGFjZXNSZXNwb25zZRIqCgp3b3Jrc3BhY2VzGAEgAygLMhYubGFwcC53ZWIudjEuV29ya3NwYWNlIiMKE0dldFdvcmtzcGFjZVJlcXVlc3QSDAoEbmFtZRgBIAEoCSJBChRHZXRXb3Jrc3BhY2VSZXNwb25zZRIpCgl3b3Jrc3BhY2UYASABKAsyFi5sYXBwLndlYi52MS5Xb3Jrc3BhY2UiLgoWQ3JlYXRlV29ya3NwYWNlUmVxdWVzdBIUCgx3b3Jrc3BhY2VfaWQYASABKAkiRAoXQ3JlYXRlV29ya3NwYWNlUmVzcG9uc2USKQoJd29ya3NwYWNlGAEgASgLMhYubGFwcC53ZWIudjEuV29ya3NwYWNlIiYKFkRlbGV0ZVdvcmtzcGFjZVJlcXVlc3QSDAoEbmFtZRgBIAEoCSIZChdEZWxldGVXb3Jrc3BhY2VSZXNwb25zZSIlChNMaXN0TG9nRmlsZXNSZXF1ZXN0Eg4KBnBhcmVudBgBIAEoCSI/ChRMaXN0TG9nRmlsZXNSZXNwb25zZRInCglsb2dfZmlsZXMYASADKAsyFC5sYXBwLndlYi52MS5Mb2dGaWxlIkoKFFVwbG9hZExvZ0ZpbGVSZXF1ZXN0Eg4KBnBhcmVudBgBIAEoCRIRCglmaWxlX25hbWUYAiABKAkSDwoHY29udGVudBgDIAEoDCI/ChVVcGxvYWRMb2dGaWxlUmVzcG9uc2USJgoIbG9nX2ZpbGUYASABKAsyFC5sYXBwLndlYi52MS5Mb2dGaWxlIiQKFERlbGV0ZUxvZ0ZpbGVSZXF1ZXN0EgwKBG5hbWUYASABKAkiFwoVRGVsZXRlTG9nRmlsZVJlc3BvbnNlIqoBChZDcmVhdGVJbXBvcnRSdW5SZXF1ZXN0Eg4KBnBhcmVudBgBIAEoCRIPCgdwcm9qZWN0GAIgASgJEg4KBmZpbHRlchgDIAEoCRIoCgRmcm9tGAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBImCgJ0bxgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASDQoFbGltaXQYBiABKAUiRQoXQ3JlYXRlSW1wb3J0UnVuUmVzcG9uc2USKgoKaW1wb3J0X3J1bhgBIAEoCzIWLmxhcHAud2ViLnYxLkltcG9ydFJ1biIjChNHZXRJbXBvcnRSdW5SZXF1ZXN0EgwKBG5hbWUYASABKAkiQgoUR2V0SW1wb3J0UnVuUmVzcG9uc2USKgoKaW1wb3J0X3J1bhgBIAEoCzIWLmxhcHAud2ViLnYxLkltcG9ydFJ1biInChVMaXN0SW1wb3J0UnVuc1JlcXVlc3QSDgoGcGFyZW50GAEgASgJIkUKFkxpc3RJbXBvcnRSdW5zUmVzcG9uc2USKwoLaW1wb3J0X3J1bnMYASADKAsyFi5sYXBwLndlYi52MS5JbXBvcnRSdW4iIAoeTGlzdFJlY2VudEltcG9ydFF1ZXJpZXNSZXF1ZXN0ImYKEVJlY2VudEltcG9ydFF1ZXJ5Eg8KB3Byb2plY3QYASABKAkSDgoGZmlsdGVyGAIgASgJEjAKDGxhc3RfdXNlZF9hdBgDIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiWQofTGlzdFJlY2VudEltcG9ydFF1ZXJpZXNSZXNwb25zZRI2Cg5yZWNlbnRfcXVlcmllcxgBIAMoCzIeLmxhcHAud2ViLnYxLlJlY2VudEltcG9ydFF1ZXJ5IjoKGUNyZWF0ZURpc2NvdmVyeVJ1blJlcXVlc3QSDgoGcGFyZW50GAEgASgJEg0KBW1vZGVsGAIgASgJIk4KGkNyZWF0ZURpc2NvdmVyeVJ1blJlc3BvbnNlEjAKDWRpc2NvdmVyeV9ydW4YASABKAsyGS5sYXBwLndlYi52MS5EaXNjb3ZlcnlSdW4iJgoWR2V0RGlzY292ZXJ5UnVuUmVxdWVzdBIMCgRuYW1lGAEgASgJIksKF0dldERpc2NvdmVyeVJ1blJlc3BvbnNlEjAKDWRpc2NvdmVyeV9ydW4YASABKAsyGS5sYXBwLndlYi52MS5EaXNjb3ZlcnlSdW4iKgoYTGlzdERpc2NvdmVyeVJ1bnNSZXF1ZXN0Eg4KBnBhcmVudBgBIAEoCSJOChlMaXN0RGlzY292ZXJ5UnVuc1Jlc3BvbnNlEjEKDmRpc2NvdmVyeV9ydW5zGAEgAygLMhkubGFwcC53ZWIudjEuRGlzY292ZXJ5UnVuIiUKE0xpc3RQYXR0ZXJuc1JlcXVlc3QSDgoGcGFyZW50GAEgASgJIj4KFExpc3RQYXR0ZXJuc1Jlc3BvbnNlEiYKCHBhdHRlcm5zGAEgAygLMhQubGFwcC53ZWIudjEuUGF0dGVybiIhChFHZXRQYXR0ZXJuUmVxdWVzdBIMCgRuYW1lGAEgASgJIjsKEkdldFBhdHRlcm5SZXNwb25zZRIlCgdwYXR0ZXJuGAEgASgLMhQubGFwcC53ZWIudjEuUGF0dGVybiImChRHZXRFcnJvcnNWaWV3UmVxdWVzdBIOCgZwYXJlbnQYASABKAkiigEKFUdldEVycm9yc1ZpZXdSZXNwb25zZRIxCg5lcnJvcl9wYXR0ZXJucxgBIAMoCzIZLmxhcHAud2ViLnYxLkVycm9yUGF0dGVybhI+ChV1bm1hdGNoZWRfZXJyb3JfbGluZXMYAiADKAsyHy5sYXBwLndlYi52MS5Vbm1hdGNoZWRFcnJvckxpbmUqqgEKD1dvcmtzcGFjZVN0YXR1cxIgChxXT1JLU1BBQ0VfU1RBVFVTX1VOU1BFQ0lGSUVEEAASGgoWV09SS1NQQUNFX1NUQVRVU19FTVBUWRABEiAKHFdPUktTUEFDRV9TVEFUVVNfRElTQ09WRVJJTkcQAhIaChZXT1JLU1BBQ0VfU1RBVFVTX1JFQURZEAMSGwoXV09SS1NQQUNFX1NUQVRVU19GQUlMRUQQBCqqAQoOSW1wb3J0UnVuU3RhdGUSIAocSU1QT1JUX1JVTl9TVEFURV9VTlNQRUNJRklFRBAAEhsKF0lNUE9SVF9SVU5fU1RBVEVfUVVFVUVEEAESHAoYSU1QT1JUX1JVTl9TVEFURV9SVU5OSU5HEAISHgoaSU1QT1JUX1JVTl9TVEFURV9TVUNDRUVERUQQAxIbChdJTVBPUlRfUlVOX1NUQVRFX0ZBSUxFRBAEKrwBChFEaXNjb3ZlcnlSdW5TdGF0ZRIjCh9ESVNDT1ZFUllfUlVOX1NUQVRFX1VOU1BFQ0lGSUVEEAASHgoaRElTQ09WRVJZX1JVTl9TVEFURV9RVUVVRUQQARIfChtESVNDT1ZFUllfUlVOX1NUQVRFX1JVTk5JTkcQAhIhCh1ESVNDT1ZFUllfUlVOX1NUQVRFX1NVQ0NFRURFRBADEh4KGkRJU0NPVkVSWV9SVU5fU1RBVEVfRkFJTEVEEAQq5wEKDURpc2NvdmVyeVN0ZXASHgoaRElTQ09WRVJZX1NURVBfVU5TUEVDSUZJRUQQABIfChtESVNDT1ZFUllfU1RFUF9SRUFESU5HX0xPR1MQARIiCh5ESVNDT1ZFUllfU1RFUF9NRVJHSU5HX0VOVFJJRVMQAhInCiNESVNDT1ZFUllfU1RFUF9ESVNDT1ZFUklOR19QQVRURVJOUxADEiQKIERJU0NPVkVSWV9TVEVQX0xBQkVMSU5HX1BBVFRFUk5TEAQSIgoeRElTQ09WRVJZX1NURVBfV1JJVElOR19SRVNVTFRTEAUyrAwKEFdvcmtzcGFjZVNlcnZpY2USWQoOTGlzdFdvcmtzcGFjZXMSIi5sYXBwLndlYi52MS5MaXN0V29ya3NwYWNlc1JlcXVlc3QaIy5sYXBwLndlYi52MS5MaXN0V29ya3NwYWNlc1Jlc3BvbnNlElMKDEdldFdvcmtzcGFjZRIgLmxhcHAud2ViLnYxLkdldFdvcmtzcGFjZVJlcXVlc3QaIS5sYXBwLndlYi52MS5HZXRXb3Jrc3BhY2VSZXNwb25zZRJcCg9DcmVhdGVXb3Jrc3BhY2USIy5sYXBwLndlYi52MS5DcmVhdGVXb3Jrc3BhY2VSZXF1ZXN0GiQubGFwcC53ZWIudjEuQ3JlYXRlV29ya3NwYWNlUmVzcG9uc2USXAoPRGVsZXRlV29ya3NwYWNlEiMubGFwcC53ZWIudjEuRGVsZXRlV29ya3NwYWNlUmVxdWVzdBokLmxhcHAud2ViLnYxLkRlbGV0ZVdvcmtzcGFjZVJlc3BvbnNlElMKDExpc3RMb2dGaWxlcxIgLmxhcHAud2ViLnYxLkxpc3RMb2dGaWxlc1JlcXVlc3QaIS5sYXBwLndlYi52MS5MaXN0TG9nRmlsZXNSZXNwb25zZRJWCg1VcGxvYWRMb2dGaWxlEiEubGFwcC53ZWIudjEuVXBsb2FkTG9nRmlsZVJlcXVlc3QaIi5sYXBwLndlYi52MS5VcGxvYWRMb2dGaWxlUmVzcG9uc2USVgoNRGVsZXRlTG9nRmlsZRIhLmxhcHAud2ViLnYxLkRlbGV0ZUxvZ0ZpbGVSZXF1ZXN0GiIubGFwcC53ZWIudjEuRGVsZXRlTG9nRmlsZVJlc3BvbnNlElwKD0NyZWF0ZUltcG9ydFJ1bhIjLmxhcHAud2ViLnYxLkNyZWF0ZUltcG9ydFJ1blJlcXVlc3QaJC5sYXBwLndlYi52MS5DcmVhdGVJbXBvcnRSdW5SZXNwb25zZRJTCgxHZXRJbXBvcnRSdW4SIC5sYXBwLndlYi52MS5HZXRJbXBvcnRSdW5SZXF1ZXN0GiEubGFwcC53ZWIudjEuR2V0SW1wb3J0UnVuUmVzcG9uc2USWQoOTGlzdEltcG9ydFJ1bnMSIi5sYXBwLndlYi52MS5MaXN0SW1wb3J0UnVuc1JlcXVlc3QaIy5sYXBwLndlYi52MS5MaXN0SW1wb3J0UnVuc1Jlc3BvbnNlEnQKF0xpc3RSZWNlbnRJbXBvcnRRdWVyaWVzEisubGFwcC53ZWIudjEuTGlzdFJlY2VudEltcG9ydFF1ZXJpZXNSZXF1ZXN0GiwubGFwcC53ZWIudjEuTGlzdFJlY2VudEltcG9ydFF1ZXJpZXNSZXNwb25zZRJlChJDcmVhdGVEaXNjb3ZlcnlSdW4SJi5sYXBwLndlYi52MS5DcmVhdGVEaXNjb3ZlcnlSdW5SZXF1ZXN0GicubGFwcC53ZWIudjEuQ3JlYXRlRGlzY292ZXJ5UnVuUmVzcG9uc2USXAoPR2V0RGlzY292ZXJ5UnVuEiMubGFwcC53ZWIudjEuR2V0RGlzY292ZXJ5UnVuUmVxdWVzdBokLmxhcHAud2ViLnYxLkdldERpc2NvdmVyeVJ1blJlc3BvbnNlEmIKEUxpc3REaXNjb3ZlcnlSdW5zEiUubGFwcC53ZWIudjEuTGlzdERpc2NvdmVyeVJ1bnNSZXF1ZXN0GiYubGFwcC53ZWIudjEuTGlzdERpc2NvdmVyeVJ1bnNSZXNwb25zZRJTCgxMaXN0UGF0dGVybnMSIC5sYXBwLndlYi52MS5MaXN0UGF0dGVybnNSZXF1ZXN0GiEubGFwcC53ZWIudjEuTGlzdFBhdHRlcm5zUmVzcG9uc2USTQoKR2V0UGF0dGVybhIeLmxhcHAud2ViLnYxLkdldFBhdHRlcm5SZXF1ZXN0Gh8ubGFwcC53ZWIudjEuR2V0UGF0dGVyblJlc3BvbnNlElYKDUdldEVycm9yc1ZpZXcSIS5sYXBwLndlYi52MS5HZXRFcnJvcnNWaWV3UmVxdWVzdBoiLmxhcHAud2ViLnYxLkdldEVycm9yc1ZpZXdSZXNwb25zZUIwWi5naXRodWIuY29tL3N0cnJsL2xhcHAvZ2VuL2dvL2xhcHAvd2ViL3YxO3dlYnYxYgZwcm90bzM", [file_google_protobuf_timestamp]); + fileDesc("ChVsYXBwL3dlYi92MS93ZWIucHJvdG8SC2xhcHAud2ViLnYxIokCCglXb3Jrc3BhY2USDAoEbmFtZRgBIAEoCRIUCgx3b3Jrc3BhY2VfaWQYAiABKAkSLAoGc3RhdHVzGAMgASgOMhwubGFwcC53ZWIudjEuV29ya3NwYWNlU3RhdHVzEhYKDmxvZ19maWxlX2NvdW50GAQgASgFEhUKDXBhdHRlcm5fY291bnQYBSABKAUSNwoUbGF0ZXN0X2Rpc2NvdmVyeV9ydW4YBiABKAsyGS5sYXBwLndlYi52MS5EaXNjb3ZlcnlSdW4SQgofbGF0ZXN0X3N1Y2Nlc3NmdWxfZGlzY292ZXJ5X3J1bhgHIAEoCzIZLmxhcHAud2ViLnYxLkRpc2NvdmVyeVJ1biJuCgdMb2dGaWxlEgwKBG5hbWUYASABKAkSEQoJZmlsZV9uYW1lGAIgASgJEhIKCnNpemVfYnl0ZXMYAyABKAMSLgoKdXBkYXRlZF9hdBgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAivAMKCUltcG9ydFJ1bhIMCgRuYW1lGAEgASgJEhUKDWltcG9ydF9ydW5faWQYAiABKAkSEAoIcHJvdmlkZXIYAyABKAkSDwoHcHJvamVjdBgEIAEoCRIOCgZmaWx0ZXIYBSABKAkSKAoEZnJvbRgGIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASJgoCdG8YByABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEg0KBWxpbWl0GAggASgFEioKBXN0YXRlGAkgASgOMhsubGFwcC53ZWIudjEuSW1wb3J0UnVuU3RhdGUSEwoLZW50cnlfY291bnQYCiABKAUSEQoJdHJ1bmNhdGVkGAsgASgIEhUKDWxvZ19maWxlX25hbWUYDCABKAkSLgoKc3RhcnRlZF9hdBgNIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLwoLZmluaXNoZWRfYXQYDiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEioKBWVycm9yGA8gASgLMhsubGFwcC53ZWIudjEuSW1wb3J0UnVuRXJyb3IiPwoRSW1wb3J0UnVuTWV0YWRhdGESKgoKaW1wb3J0X3J1bhgBIAEoCzIWLmxhcHAud2ViLnYxLkltcG9ydFJ1biIvCg5JbXBvcnRSdW5FcnJvchIMCgRjb2RlGAEgASgJEg8KB21lc3NhZ2UYAiABKAki3QMKDERpc2NvdmVyeVJ1bhIMCgRuYW1lGAEgASgJEhgKEGRpc2NvdmVyeV9ydW5faWQYAiABKAkSLQoFc3RhdGUYAyABKA4yHi5sYXBwLndlYi52MS5EaXNjb3ZlcnlSdW5TdGF0ZRIwCgxjdXJyZW50X3N0ZXAYBCABKA4yGi5sYXBwLndlYi52MS5EaXNjb3ZlcnlTdGVwEhwKEHByb2dyZXNzX21lc3NhZ2UYBSABKAlCAhgBEhkKDWVycm9yX21lc3NhZ2UYBiABKAlCAhgBEi4KCnN0YXJ0ZWRfYXQYByABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi8KC2ZpbmlzaGVkX2F0GAggASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIWCg5sb2dfZmlsZV9jb3VudBgJIAEoBRIVCg1wYXR0ZXJuX2NvdW50GAogASgFEhcKD3VubWF0Y2hlZF9jb3VudBgLIAEoBRIzCghwcm9ncmVzcxgMIAEoCzIhLmxhcHAud2ViLnYxLkRpc2NvdmVyeVJ1blByb2dyZXNzEi0KBWVycm9yGA0gASgLMh4ubGFwcC53ZWIudjEuRGlzY292ZXJ5UnVuRXJyb3IiSAoURGlzY292ZXJ5UnVuTWV0YWRhdGESMAoNZGlzY292ZXJ5X3J1bhgBIAEoCzIZLmxhcHAud2ViLnYxLkRpc2NvdmVyeVJ1biJ/ChREaXNjb3ZlcnlSdW5Qcm9ncmVzcxIoCgRzdGVwGAEgASgOMhoubGFwcC53ZWIudjEuRGlzY292ZXJ5U3RlcBI9CgtsYWJlbF9iYXRjaBgCIAEoCzIoLmxhcHAud2ViLnYxLkRpc2NvdmVyeUxhYmVsQmF0Y2hQcm9ncmVzcyKrAQobRGlzY292ZXJ5TGFiZWxCYXRjaFByb2dyZXNzEg0KBWV2ZW50GAEgASgJEhQKDGJhdGNoX251bWJlchgCIAEoBRITCgtiYXRjaF9jb3VudBgDIAEoBRISCgpiYXRjaF9zaXplGAQgASgFEg8KB2F0dGVtcHQYBSABKAUSFAoMbWF4X2F0dGVtcHRzGAYgASgFEhcKD2NvbXBsZXRlZF9jb3VudBgHIAEoBSJcChFEaXNjb3ZlcnlSdW5FcnJvchIMCgRjb2RlGAEgASgJEg8KB21lc3NhZ2UYAiABKAkSKAoEc3RlcBgDIAEoDjIaLmxhcHAud2ViLnYxLkRpc2NvdmVyeVN0ZXAigwIKB1BhdHRlcm4SDAoEbmFtZRgBIAEoCRISCgpwYXR0ZXJuX2lkGAIgASgJEhMKC3NlbWFudGljX2lkGAMgASgJEhMKC2Rlc2NyaXB0aW9uGAQgASgJEhAKCHRlbXBsYXRlGAUgASgJEg0KBWNvdW50GAYgASgFEigKCmZpcnN0X3NlZW4YByABKAsyFC5sYXBwLndlYi52MS5MaW5lUmVmEicKCWxhc3Rfc2VlbhgIIAEoCzIULmxhcHAud2ViLnYxLkxpbmVSZWYSJwoJbGluZV9yZWZzGAkgAygLMhQubGFwcC53ZWIudjEuTGluZVJlZhIPCgdzYW1wbGVzGAogAygJIjEKB0xpbmVSZWYSEQoJZmlsZV9uYW1lGAEgASgJEhMKC2xpbmVfbnVtYmVyGAIgASgFIjUKDEVycm9yUGF0dGVybhIlCgdwYXR0ZXJuGAEgASgLMhQubGFwcC53ZWIudjEuUGF0dGVybiJNChJVbm1hdGNoZWRFcnJvckxpbmUSEQoJZmlsZV9uYW1lGAEgASgJEhMKC2xpbmVfbnVtYmVyGAIgASgFEg8KB2NvbnRlbnQYAyABKAkiFwoVTGlzdFdvcmtzcGFjZXNSZXF1ZXN0IkQKFkxpc3RXb3Jrc3BhY2VzUmVzcG9uc2USKgoKd29ya3NwYWNlcxgBIAMoCzIWLmxhcHAud2ViLnYxLldvcmtzcGFjZSIjChNHZXRXb3Jrc3BhY2VSZXF1ZXN0EgwKBG5hbWUYASABKAkiQQoUR2V0V29ya3NwYWNlUmVzcG9uc2USKQoJd29ya3NwYWNlGAEgASgLMhYubGFwcC53ZWIudjEuV29ya3NwYWNlIi4KFkNyZWF0ZVdvcmtzcGFjZVJlcXVlc3QSFAoMd29ya3NwYWNlX2lkGAEgASgJIkQKF0NyZWF0ZVdvcmtzcGFjZVJlc3BvbnNlEikKCXdvcmtzcGFjZRgBIAEoCzIWLmxhcHAud2ViLnYxLldvcmtzcGFjZSImChZEZWxldGVXb3Jrc3BhY2VSZXF1ZXN0EgwKBG5hbWUYASABKAkiGQoXRGVsZXRlV29ya3NwYWNlUmVzcG9uc2UiJQoTTGlzdExvZ0ZpbGVzUmVxdWVzdBIOCgZwYXJlbnQYASABKAkiPwoUTGlzdExvZ0ZpbGVzUmVzcG9uc2USJwoJbG9nX2ZpbGVzGAEgAygLMhQubGFwcC53ZWIudjEuTG9nRmlsZSJKChRVcGxvYWRMb2dGaWxlUmVxdWVzdBIOCgZwYXJlbnQYASABKAkSEQoJZmlsZV9uYW1lGAIgASgJEg8KB2NvbnRlbnQYAyABKAwiPwoVVXBsb2FkTG9nRmlsZVJlc3BvbnNlEiYKCGxvZ19maWxlGAEgASgLMhQubGFwcC53ZWIudjEuTG9nRmlsZSIkChREZWxldGVMb2dGaWxlUmVxdWVzdBIMCgRuYW1lGAEgASgJIhcKFURlbGV0ZUxvZ0ZpbGVSZXNwb25zZSKqAQoWQ3JlYXRlSW1wb3J0UnVuUmVxdWVzdBIOCgZwYXJlbnQYASABKAkSDwoHcHJvamVjdBgCIAEoCRIOCgZmaWx0ZXIYAyABKAkSKAoEZnJvbRgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASJgoCdG8YBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEg0KBWxpbWl0GAYgASgFIiMKE0dldEltcG9ydFJ1blJlcXVlc3QSDAoEbmFtZRgBIAEoCSJCChRHZXRJbXBvcnRSdW5SZXNwb25zZRIqCgppbXBvcnRfcnVuGAEgASgLMhYubGFwcC53ZWIudjEuSW1wb3J0UnVuIicKFUxpc3RJbXBvcnRSdW5zUmVxdWVzdBIOCgZwYXJlbnQYASABKAkiRQoWTGlzdEltcG9ydFJ1bnNSZXNwb25zZRIrCgtpbXBvcnRfcnVucxgBIAMoCzIWLmxhcHAud2ViLnYxLkltcG9ydFJ1biIgCh5MaXN0UmVjZW50SW1wb3J0UXVlcmllc1JlcXVlc3QiZgoRUmVjZW50SW1wb3J0UXVlcnkSDwoHcHJvamVjdBgBIAEoCRIOCgZmaWx0ZXIYAiABKAkSMAoMbGFzdF91c2VkX2F0GAMgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcCJZCh9MaXN0UmVjZW50SW1wb3J0UXVlcmllc1Jlc3BvbnNlEjYKDnJlY2VudF9xdWVyaWVzGAEgAygLMh4ubGFwcC53ZWIudjEuUmVjZW50SW1wb3J0UXVlcnkiOgoZQ3JlYXRlRGlzY292ZXJ5UnVuUmVxdWVzdBIOCgZwYXJlbnQYASABKAkSDQoFbW9kZWwYAiABKAkiJgoWR2V0RGlzY292ZXJ5UnVuUmVxdWVzdBIMCgRuYW1lGAEgASgJIksKF0dldERpc2NvdmVyeVJ1blJlc3BvbnNlEjAKDWRpc2NvdmVyeV9ydW4YASABKAsyGS5sYXBwLndlYi52MS5EaXNjb3ZlcnlSdW4iKgoYTGlzdERpc2NvdmVyeVJ1bnNSZXF1ZXN0Eg4KBnBhcmVudBgBIAEoCSJOChlMaXN0RGlzY292ZXJ5UnVuc1Jlc3BvbnNlEjEKDmRpc2NvdmVyeV9ydW5zGAEgAygLMhkubGFwcC53ZWIudjEuRGlzY292ZXJ5UnVuIiUKE0xpc3RQYXR0ZXJuc1JlcXVlc3QSDgoGcGFyZW50GAEgASgJIj4KFExpc3RQYXR0ZXJuc1Jlc3BvbnNlEiYKCHBhdHRlcm5zGAEgAygLMhQubGFwcC53ZWIudjEuUGF0dGVybiIhChFHZXRQYXR0ZXJuUmVxdWVzdBIMCgRuYW1lGAEgASgJIjsKEkdldFBhdHRlcm5SZXNwb25zZRIlCgdwYXR0ZXJuGAEgASgLMhQubGFwcC53ZWIudjEuUGF0dGVybiImChRHZXRFcnJvcnNWaWV3UmVxdWVzdBIOCgZwYXJlbnQYASABKAkiigEKFUdldEVycm9yc1ZpZXdSZXNwb25zZRIxCg5lcnJvcl9wYXR0ZXJucxgBIAMoCzIZLmxhcHAud2ViLnYxLkVycm9yUGF0dGVybhI+ChV1bm1hdGNoZWRfZXJyb3JfbGluZXMYAiADKAsyHy5sYXBwLndlYi52MS5Vbm1hdGNoZWRFcnJvckxpbmUqqgEKD1dvcmtzcGFjZVN0YXR1cxIgChxXT1JLU1BBQ0VfU1RBVFVTX1VOU1BFQ0lGSUVEEAASGgoWV09SS1NQQUNFX1NUQVRVU19FTVBUWRABEiAKHFdPUktTUEFDRV9TVEFUVVNfRElTQ09WRVJJTkcQAhIaChZXT1JLU1BBQ0VfU1RBVFVTX1JFQURZEAMSGwoXV09SS1NQQUNFX1NUQVRVU19GQUlMRUQQBCqqAQoOSW1wb3J0UnVuU3RhdGUSIAocSU1QT1JUX1JVTl9TVEFURV9VTlNQRUNJRklFRBAAEhsKF0lNUE9SVF9SVU5fU1RBVEVfUVVFVUVEEAESHAoYSU1QT1JUX1JVTl9TVEFURV9SVU5OSU5HEAISHgoaSU1QT1JUX1JVTl9TVEFURV9TVUNDRUVERUQQAxIbChdJTVBPUlRfUlVOX1NUQVRFX0ZBSUxFRBAEKrwBChFEaXNjb3ZlcnlSdW5TdGF0ZRIjCh9ESVNDT1ZFUllfUlVOX1NUQVRFX1VOU1BFQ0lGSUVEEAASHgoaRElTQ09WRVJZX1JVTl9TVEFURV9RVUVVRUQQARIfChtESVNDT1ZFUllfUlVOX1NUQVRFX1JVTk5JTkcQAhIhCh1ESVNDT1ZFUllfUlVOX1NUQVRFX1NVQ0NFRURFRBADEh4KGkRJU0NPVkVSWV9SVU5fU1RBVEVfRkFJTEVEEAQq5wEKDURpc2NvdmVyeVN0ZXASHgoaRElTQ09WRVJZX1NURVBfVU5TUEVDSUZJRUQQABIfChtESVNDT1ZFUllfU1RFUF9SRUFESU5HX0xPR1MQARIiCh5ESVNDT1ZFUllfU1RFUF9NRVJHSU5HX0VOVFJJRVMQAhInCiNESVNDT1ZFUllfU1RFUF9ESVNDT1ZFUklOR19QQVRURVJOUxADEiQKIERJU0NPVkVSWV9TVEVQX0xBQkVMSU5HX1BBVFRFUk5TEAQSIgoeRElTQ09WRVJZX1NURVBfV1JJVElOR19SRVNVTFRTEAUy6AwKEFdvcmtzcGFjZVNlcnZpY2USWQoOTGlzdFdvcmtzcGFjZXMSIi5sYXBwLndlYi52MS5MaXN0V29ya3NwYWNlc1JlcXVlc3QaIy5sYXBwLndlYi52MS5MaXN0V29ya3NwYWNlc1Jlc3BvbnNlElMKDEdldFdvcmtzcGFjZRIgLmxhcHAud2ViLnYxLkdldFdvcmtzcGFjZVJlcXVlc3QaIS5sYXBwLndlYi52MS5HZXRXb3Jrc3BhY2VSZXNwb25zZRJcCg9DcmVhdGVXb3Jrc3BhY2USIy5sYXBwLndlYi52MS5DcmVhdGVXb3Jrc3BhY2VSZXF1ZXN0GiQubGFwcC53ZWIudjEuQ3JlYXRlV29ya3NwYWNlUmVzcG9uc2USXAoPRGVsZXRlV29ya3NwYWNlEiMubGFwcC53ZWIudjEuRGVsZXRlV29ya3NwYWNlUmVxdWVzdBokLmxhcHAud2ViLnYxLkRlbGV0ZVdvcmtzcGFjZVJlc3BvbnNlElMKDExpc3RMb2dGaWxlcxIgLmxhcHAud2ViLnYxLkxpc3RMb2dGaWxlc1JlcXVlc3QaIS5sYXBwLndlYi52MS5MaXN0TG9nRmlsZXNSZXNwb25zZRJWCg1VcGxvYWRMb2dGaWxlEiEubGFwcC53ZWIudjEuVXBsb2FkTG9nRmlsZVJlcXVlc3QaIi5sYXBwLndlYi52MS5VcGxvYWRMb2dGaWxlUmVzcG9uc2USVgoNRGVsZXRlTG9nRmlsZRIhLmxhcHAud2ViLnYxLkRlbGV0ZUxvZ0ZpbGVSZXF1ZXN0GiIubGFwcC53ZWIudjEuRGVsZXRlTG9nRmlsZVJlc3BvbnNlEngKD0NyZWF0ZUltcG9ydFJ1bhIjLmxhcHAud2ViLnYxLkNyZWF0ZUltcG9ydFJ1blJlcXVlc3QaHS5nb29nbGUubG9uZ3J1bm5pbmcuT3BlcmF0aW9uIiHKQR4KCUltcG9ydFJ1bhIRSW1wb3J0UnVuTWV0YWRhdGESUwoMR2V0SW1wb3J0UnVuEiAubGFwcC53ZWIudjEuR2V0SW1wb3J0UnVuUmVxdWVzdBohLmxhcHAud2ViLnYxLkdldEltcG9ydFJ1blJlc3BvbnNlElkKDkxpc3RJbXBvcnRSdW5zEiIubGFwcC53ZWIudjEuTGlzdEltcG9ydFJ1bnNSZXF1ZXN0GiMubGFwcC53ZWIudjEuTGlzdEltcG9ydFJ1bnNSZXNwb25zZRJ0ChdMaXN0UmVjZW50SW1wb3J0UXVlcmllcxIrLmxhcHAud2ViLnYxLkxpc3RSZWNlbnRJbXBvcnRRdWVyaWVzUmVxdWVzdBosLmxhcHAud2ViLnYxLkxpc3RSZWNlbnRJbXBvcnRRdWVyaWVzUmVzcG9uc2UShAEKEkNyZWF0ZURpc2NvdmVyeVJ1bhImLmxhcHAud2ViLnYxLkNyZWF0ZURpc2NvdmVyeVJ1blJlcXVlc3QaHS5nb29nbGUubG9uZ3J1bm5pbmcuT3BlcmF0aW9uIifKQSQKDERpc2NvdmVyeVJ1bhIURGlzY292ZXJ5UnVuTWV0YWRhdGESXAoPR2V0RGlzY292ZXJ5UnVuEiMubGFwcC53ZWIudjEuR2V0RGlzY292ZXJ5UnVuUmVxdWVzdBokLmxhcHAud2ViLnYxLkdldERpc2NvdmVyeVJ1blJlc3BvbnNlEmIKEUxpc3REaXNjb3ZlcnlSdW5zEiUubGFwcC53ZWIudjEuTGlzdERpc2NvdmVyeVJ1bnNSZXF1ZXN0GiYubGFwcC53ZWIudjEuTGlzdERpc2NvdmVyeVJ1bnNSZXNwb25zZRJTCgxMaXN0UGF0dGVybnMSIC5sYXBwLndlYi52MS5MaXN0UGF0dGVybnNSZXF1ZXN0GiEubGFwcC53ZWIudjEuTGlzdFBhdHRlcm5zUmVzcG9uc2USTQoKR2V0UGF0dGVybhIeLmxhcHAud2ViLnYxLkdldFBhdHRlcm5SZXF1ZXN0Gh8ubGFwcC53ZWIudjEuR2V0UGF0dGVyblJlc3BvbnNlElYKDUdldEVycm9yc1ZpZXcSIS5sYXBwLndlYi52MS5HZXRFcnJvcnNWaWV3UmVxdWVzdBoiLmxhcHAud2ViLnYxLkdldEVycm9yc1ZpZXdSZXNwb25zZUIwWi5naXRodWIuY29tL3N0cnJsL2xhcHAvZ2VuL2dvL2xhcHAvd2ViL3YxO3dlYnYxYgZwcm90bzM", [file_google_longrunning_operations, file_google_protobuf_timestamp]); /** * @generated from message lapp.web.v1.Workspace @@ -180,6 +182,23 @@ export type ImportRun = Message<"lapp.web.v1.ImportRun"> & { export const ImportRunSchema: GenMessage = /*@__PURE__*/ messageDesc(file_lapp_web_v1_web, 2); +/** + * @generated from message lapp.web.v1.ImportRunMetadata + */ +export type ImportRunMetadata = Message<"lapp.web.v1.ImportRunMetadata"> & { + /** + * @generated from field: lapp.web.v1.ImportRun import_run = 1; + */ + importRun?: ImportRun | undefined; +}; + +/** + * Describes the message lapp.web.v1.ImportRunMetadata. + * Use `create(ImportRunMetadataSchema)` to create a new message. + */ +export const ImportRunMetadataSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_lapp_web_v1_web, 3); + /** * @generated from message lapp.web.v1.ImportRunError */ @@ -200,7 +219,7 @@ export type ImportRunError = Message<"lapp.web.v1.ImportRunError"> & { * Use `create(ImportRunErrorSchema)` to create a new message. */ export const ImportRunErrorSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 3); + messageDesc(file_lapp_web_v1_web, 4); /** * @generated from message lapp.web.v1.DiscoveryRun @@ -279,7 +298,24 @@ export type DiscoveryRun = Message<"lapp.web.v1.DiscoveryRun"> & { * Use `create(DiscoveryRunSchema)` to create a new message. */ export const DiscoveryRunSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 4); + messageDesc(file_lapp_web_v1_web, 5); + +/** + * @generated from message lapp.web.v1.DiscoveryRunMetadata + */ +export type DiscoveryRunMetadata = Message<"lapp.web.v1.DiscoveryRunMetadata"> & { + /** + * @generated from field: lapp.web.v1.DiscoveryRun discovery_run = 1; + */ + discoveryRun?: DiscoveryRun | undefined; +}; + +/** + * Describes the message lapp.web.v1.DiscoveryRunMetadata. + * Use `create(DiscoveryRunMetadataSchema)` to create a new message. + */ +export const DiscoveryRunMetadataSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_lapp_web_v1_web, 6); /** * @generated from message lapp.web.v1.DiscoveryRunProgress @@ -301,7 +337,7 @@ export type DiscoveryRunProgress = Message<"lapp.web.v1.DiscoveryRunProgress"> & * Use `create(DiscoveryRunProgressSchema)` to create a new message. */ export const DiscoveryRunProgressSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 5); + messageDesc(file_lapp_web_v1_web, 7); /** * @generated from message lapp.web.v1.DiscoveryLabelBatchProgress @@ -348,7 +384,7 @@ export type DiscoveryLabelBatchProgress = Message<"lapp.web.v1.DiscoveryLabelBat * Use `create(DiscoveryLabelBatchProgressSchema)` to create a new message. */ export const DiscoveryLabelBatchProgressSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 6); + messageDesc(file_lapp_web_v1_web, 8); /** * @generated from message lapp.web.v1.DiscoveryRunError @@ -375,7 +411,7 @@ export type DiscoveryRunError = Message<"lapp.web.v1.DiscoveryRunError"> & { * Use `create(DiscoveryRunErrorSchema)` to create a new message. */ export const DiscoveryRunErrorSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 7); + messageDesc(file_lapp_web_v1_web, 9); /** * @generated from message lapp.web.v1.Pattern @@ -437,7 +473,7 @@ export type Pattern = Message<"lapp.web.v1.Pattern"> & { * Use `create(PatternSchema)` to create a new message. */ export const PatternSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 8); + messageDesc(file_lapp_web_v1_web, 10); /** * @generated from message lapp.web.v1.LineRef @@ -459,7 +495,7 @@ export type LineRef = Message<"lapp.web.v1.LineRef"> & { * Use `create(LineRefSchema)` to create a new message. */ export const LineRefSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 9); + messageDesc(file_lapp_web_v1_web, 11); /** * @generated from message lapp.web.v1.ErrorPattern @@ -476,7 +512,7 @@ export type ErrorPattern = Message<"lapp.web.v1.ErrorPattern"> & { * Use `create(ErrorPatternSchema)` to create a new message. */ export const ErrorPatternSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 10); + messageDesc(file_lapp_web_v1_web, 12); /** * @generated from message lapp.web.v1.UnmatchedErrorLine @@ -503,7 +539,7 @@ export type UnmatchedErrorLine = Message<"lapp.web.v1.UnmatchedErrorLine"> & { * Use `create(UnmatchedErrorLineSchema)` to create a new message. */ export const UnmatchedErrorLineSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 11); + messageDesc(file_lapp_web_v1_web, 13); /** * @generated from message lapp.web.v1.ListWorkspacesRequest @@ -516,7 +552,7 @@ export type ListWorkspacesRequest = Message<"lapp.web.v1.ListWorkspacesRequest"> * Use `create(ListWorkspacesRequestSchema)` to create a new message. */ export const ListWorkspacesRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 12); + messageDesc(file_lapp_web_v1_web, 14); /** * @generated from message lapp.web.v1.ListWorkspacesResponse @@ -533,7 +569,7 @@ export type ListWorkspacesResponse = Message<"lapp.web.v1.ListWorkspacesResponse * Use `create(ListWorkspacesResponseSchema)` to create a new message. */ export const ListWorkspacesResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 13); + messageDesc(file_lapp_web_v1_web, 15); /** * @generated from message lapp.web.v1.GetWorkspaceRequest @@ -550,7 +586,7 @@ export type GetWorkspaceRequest = Message<"lapp.web.v1.GetWorkspaceRequest"> & { * Use `create(GetWorkspaceRequestSchema)` to create a new message. */ export const GetWorkspaceRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 14); + messageDesc(file_lapp_web_v1_web, 16); /** * @generated from message lapp.web.v1.GetWorkspaceResponse @@ -567,7 +603,7 @@ export type GetWorkspaceResponse = Message<"lapp.web.v1.GetWorkspaceResponse"> & * Use `create(GetWorkspaceResponseSchema)` to create a new message. */ export const GetWorkspaceResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 15); + messageDesc(file_lapp_web_v1_web, 17); /** * @generated from message lapp.web.v1.CreateWorkspaceRequest @@ -584,7 +620,7 @@ export type CreateWorkspaceRequest = Message<"lapp.web.v1.CreateWorkspaceRequest * Use `create(CreateWorkspaceRequestSchema)` to create a new message. */ export const CreateWorkspaceRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 16); + messageDesc(file_lapp_web_v1_web, 18); /** * @generated from message lapp.web.v1.CreateWorkspaceResponse @@ -601,7 +637,7 @@ export type CreateWorkspaceResponse = Message<"lapp.web.v1.CreateWorkspaceRespon * Use `create(CreateWorkspaceResponseSchema)` to create a new message. */ export const CreateWorkspaceResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 17); + messageDesc(file_lapp_web_v1_web, 19); /** * @generated from message lapp.web.v1.DeleteWorkspaceRequest @@ -618,7 +654,7 @@ export type DeleteWorkspaceRequest = Message<"lapp.web.v1.DeleteWorkspaceRequest * Use `create(DeleteWorkspaceRequestSchema)` to create a new message. */ export const DeleteWorkspaceRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 18); + messageDesc(file_lapp_web_v1_web, 20); /** * @generated from message lapp.web.v1.DeleteWorkspaceResponse @@ -631,7 +667,7 @@ export type DeleteWorkspaceResponse = Message<"lapp.web.v1.DeleteWorkspaceRespon * Use `create(DeleteWorkspaceResponseSchema)` to create a new message. */ export const DeleteWorkspaceResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 19); + messageDesc(file_lapp_web_v1_web, 21); /** * @generated from message lapp.web.v1.ListLogFilesRequest @@ -648,7 +684,7 @@ export type ListLogFilesRequest = Message<"lapp.web.v1.ListLogFilesRequest"> & { * Use `create(ListLogFilesRequestSchema)` to create a new message. */ export const ListLogFilesRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 20); + messageDesc(file_lapp_web_v1_web, 22); /** * @generated from message lapp.web.v1.ListLogFilesResponse @@ -665,7 +701,7 @@ export type ListLogFilesResponse = Message<"lapp.web.v1.ListLogFilesResponse"> & * Use `create(ListLogFilesResponseSchema)` to create a new message. */ export const ListLogFilesResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 21); + messageDesc(file_lapp_web_v1_web, 23); /** * @generated from message lapp.web.v1.UploadLogFileRequest @@ -692,7 +728,7 @@ export type UploadLogFileRequest = Message<"lapp.web.v1.UploadLogFileRequest"> & * Use `create(UploadLogFileRequestSchema)` to create a new message. */ export const UploadLogFileRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 22); + messageDesc(file_lapp_web_v1_web, 24); /** * @generated from message lapp.web.v1.UploadLogFileResponse @@ -709,7 +745,7 @@ export type UploadLogFileResponse = Message<"lapp.web.v1.UploadLogFileResponse"> * Use `create(UploadLogFileResponseSchema)` to create a new message. */ export const UploadLogFileResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 23); + messageDesc(file_lapp_web_v1_web, 25); /** * @generated from message lapp.web.v1.DeleteLogFileRequest @@ -726,7 +762,7 @@ export type DeleteLogFileRequest = Message<"lapp.web.v1.DeleteLogFileRequest"> & * Use `create(DeleteLogFileRequestSchema)` to create a new message. */ export const DeleteLogFileRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 24); + messageDesc(file_lapp_web_v1_web, 26); /** * @generated from message lapp.web.v1.DeleteLogFileResponse @@ -739,7 +775,7 @@ export type DeleteLogFileResponse = Message<"lapp.web.v1.DeleteLogFileResponse"> * Use `create(DeleteLogFileResponseSchema)` to create a new message. */ export const DeleteLogFileResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 25); + messageDesc(file_lapp_web_v1_web, 27); /** * @generated from message lapp.web.v1.CreateImportRunRequest @@ -781,24 +817,7 @@ export type CreateImportRunRequest = Message<"lapp.web.v1.CreateImportRunRequest * Use `create(CreateImportRunRequestSchema)` to create a new message. */ export const CreateImportRunRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 26); - -/** - * @generated from message lapp.web.v1.CreateImportRunResponse - */ -export type CreateImportRunResponse = Message<"lapp.web.v1.CreateImportRunResponse"> & { - /** - * @generated from field: lapp.web.v1.ImportRun import_run = 1; - */ - importRun?: ImportRun | undefined; -}; - -/** - * Describes the message lapp.web.v1.CreateImportRunResponse. - * Use `create(CreateImportRunResponseSchema)` to create a new message. - */ -export const CreateImportRunResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 27); + messageDesc(file_lapp_web_v1_web, 28); /** * @generated from message lapp.web.v1.GetImportRunRequest @@ -815,7 +834,7 @@ export type GetImportRunRequest = Message<"lapp.web.v1.GetImportRunRequest"> & { * Use `create(GetImportRunRequestSchema)` to create a new message. */ export const GetImportRunRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 28); + messageDesc(file_lapp_web_v1_web, 29); /** * @generated from message lapp.web.v1.GetImportRunResponse @@ -832,7 +851,7 @@ export type GetImportRunResponse = Message<"lapp.web.v1.GetImportRunResponse"> & * Use `create(GetImportRunResponseSchema)` to create a new message. */ export const GetImportRunResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 29); + messageDesc(file_lapp_web_v1_web, 30); /** * @generated from message lapp.web.v1.ListImportRunsRequest @@ -849,7 +868,7 @@ export type ListImportRunsRequest = Message<"lapp.web.v1.ListImportRunsRequest"> * Use `create(ListImportRunsRequestSchema)` to create a new message. */ export const ListImportRunsRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 30); + messageDesc(file_lapp_web_v1_web, 31); /** * @generated from message lapp.web.v1.ListImportRunsResponse @@ -866,7 +885,7 @@ export type ListImportRunsResponse = Message<"lapp.web.v1.ListImportRunsResponse * Use `create(ListImportRunsResponseSchema)` to create a new message. */ export const ListImportRunsResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 31); + messageDesc(file_lapp_web_v1_web, 32); /** * @generated from message lapp.web.v1.ListRecentImportQueriesRequest @@ -879,7 +898,7 @@ export type ListRecentImportQueriesRequest = Message<"lapp.web.v1.ListRecentImpo * Use `create(ListRecentImportQueriesRequestSchema)` to create a new message. */ export const ListRecentImportQueriesRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 32); + messageDesc(file_lapp_web_v1_web, 33); /** * @generated from message lapp.web.v1.RecentImportQuery @@ -906,7 +925,7 @@ export type RecentImportQuery = Message<"lapp.web.v1.RecentImportQuery"> & { * Use `create(RecentImportQuerySchema)` to create a new message. */ export const RecentImportQuerySchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 33); + messageDesc(file_lapp_web_v1_web, 34); /** * @generated from message lapp.web.v1.ListRecentImportQueriesResponse @@ -923,7 +942,7 @@ export type ListRecentImportQueriesResponse = Message<"lapp.web.v1.ListRecentImp * Use `create(ListRecentImportQueriesResponseSchema)` to create a new message. */ export const ListRecentImportQueriesResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 34); + messageDesc(file_lapp_web_v1_web, 35); /** * @generated from message lapp.web.v1.CreateDiscoveryRunRequest @@ -945,23 +964,6 @@ export type CreateDiscoveryRunRequest = Message<"lapp.web.v1.CreateDiscoveryRunR * Use `create(CreateDiscoveryRunRequestSchema)` to create a new message. */ export const CreateDiscoveryRunRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_lapp_web_v1_web, 35); - -/** - * @generated from message lapp.web.v1.CreateDiscoveryRunResponse - */ -export type CreateDiscoveryRunResponse = Message<"lapp.web.v1.CreateDiscoveryRunResponse"> & { - /** - * @generated from field: lapp.web.v1.DiscoveryRun discovery_run = 1; - */ - discoveryRun?: DiscoveryRun | undefined; -}; - -/** - * Describes the message lapp.web.v1.CreateDiscoveryRunResponse. - * Use `create(CreateDiscoveryRunResponseSchema)` to create a new message. - */ -export const CreateDiscoveryRunResponseSchema: GenMessage = /*@__PURE__*/ messageDesc(file_lapp_web_v1_web, 36); /** @@ -1354,7 +1356,7 @@ export const WorkspaceService: GenService<{ createImportRun: { methodKind: "unary"; input: typeof CreateImportRunRequestSchema; - output: typeof CreateImportRunResponseSchema; + output: typeof OperationSchema; }, /** * @generated from rpc lapp.web.v1.WorkspaceService.GetImportRun @@ -1386,7 +1388,7 @@ export const WorkspaceService: GenService<{ createDiscoveryRun: { methodKind: "unary"; input: typeof CreateDiscoveryRunRequestSchema; - output: typeof CreateDiscoveryRunResponseSchema; + output: typeof OperationSchema; }, /** * @generated from rpc lapp.web.v1.WorkspaceService.GetDiscoveryRun diff --git a/frontend/src/store.ts b/frontend/src/store.ts index 993e3aa..7404862 100644 --- a/frontend/src/store.ts +++ b/frontend/src/store.ts @@ -1,8 +1,10 @@ import { ConnectError } from "@connectrpc/connect"; +import { anyUnpack } from "@bufbuild/protobuf/wkt"; import { create } from "zustand"; import { workspaceClient } from "./api"; import { DiscoveryRun, + DiscoveryRunMetadataSchema, DiscoveryRunState, LogFile, Pattern, @@ -219,7 +221,8 @@ export const useAppStore = create()((set, get) => ({ if (!selectedWorkspaceName) return; const response = await workspaceClient.createDiscoveryRun({ parent: selectedWorkspaceName }); - set({ selectedRunName: response.discoveryRun?.name || "" }); + const metadata = response.metadata ? anyUnpack(response.metadata, DiscoveryRunMetadataSchema) : undefined; + set({ selectedRunName: metadata?.discoveryRun?.name || "" }); await get().refreshWorkspaceDetails(selectedWorkspaceName); await get().refreshWorkspaces(); } diff --git a/gen/go/google/longrunning/longrunningpbconnect/operations.connect.go b/gen/go/google/longrunning/longrunningpbconnect/operations.connect.go new file mode 100644 index 0000000..309c7c4 --- /dev/null +++ b/gen/go/google/longrunning/longrunningpbconnect/operations.connect.go @@ -0,0 +1,297 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: google/longrunning/operations.proto + +package longrunningpbconnect + +import ( + longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb" + connect "connectrpc.com/connect" + context "context" + errors "errors" + emptypb "google.golang.org/protobuf/types/known/emptypb" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // OperationsName is the fully-qualified name of the Operations service. + OperationsName = "google.longrunning.Operations" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // OperationsListOperationsProcedure is the fully-qualified name of the Operations's ListOperations + // RPC. + OperationsListOperationsProcedure = "/google.longrunning.Operations/ListOperations" + // OperationsGetOperationProcedure is the fully-qualified name of the Operations's GetOperation RPC. + OperationsGetOperationProcedure = "/google.longrunning.Operations/GetOperation" + // OperationsDeleteOperationProcedure is the fully-qualified name of the Operations's + // DeleteOperation RPC. + OperationsDeleteOperationProcedure = "/google.longrunning.Operations/DeleteOperation" + // OperationsCancelOperationProcedure is the fully-qualified name of the Operations's + // CancelOperation RPC. + OperationsCancelOperationProcedure = "/google.longrunning.Operations/CancelOperation" + // OperationsWaitOperationProcedure is the fully-qualified name of the Operations's WaitOperation + // RPC. + OperationsWaitOperationProcedure = "/google.longrunning.Operations/WaitOperation" +) + +// OperationsClient is a client for the google.longrunning.Operations service. +type OperationsClient interface { + // Lists operations that match the specified filter in the request. If the + // server doesn't support this method, it returns `UNIMPLEMENTED`. + ListOperations(context.Context, *connect.Request[longrunningpb.ListOperationsRequest]) (*connect.Response[longrunningpb.ListOperationsResponse], error) + // Gets the latest state of a long-running operation. Clients can use this + // method to poll the operation result at intervals as recommended by the API + // service. + GetOperation(context.Context, *connect.Request[longrunningpb.GetOperationRequest]) (*connect.Response[longrunningpb.Operation], error) + // Deletes a long-running operation. This method indicates that the client is + // no longer interested in the operation result. It does not cancel the + // operation. If the server doesn't support this method, it returns + // `google.rpc.Code.UNIMPLEMENTED`. + DeleteOperation(context.Context, *connect.Request[longrunningpb.DeleteOperationRequest]) (*connect.Response[emptypb.Empty], error) + // Starts asynchronous cancellation on a long-running operation. The server + // makes a best effort to cancel the operation, but success is not + // guaranteed. If the server doesn't support this method, it returns + // `google.rpc.Code.UNIMPLEMENTED`. Clients can use + // [Operations.GetOperation][google.longrunning.Operations.GetOperation] or + // other methods to check whether the cancellation succeeded or whether the + // operation completed despite cancellation. On successful cancellation, + // the operation is not deleted; instead, it becomes an operation with + // an [Operation.error][google.longrunning.Operation.error] value with a + // [google.rpc.Status.code][google.rpc.Status.code] of `1`, corresponding to + // `Code.CANCELLED`. + CancelOperation(context.Context, *connect.Request[longrunningpb.CancelOperationRequest]) (*connect.Response[emptypb.Empty], error) + // Waits until the specified long-running operation is done or reaches at most + // a specified timeout, returning the latest state. If the operation is + // already done, the latest state is immediately returned. If the timeout + // specified is greater than the default HTTP/RPC timeout, the HTTP/RPC + // timeout is used. If the server does not support this method, it returns + // `google.rpc.Code.UNIMPLEMENTED`. + // Note that this method is on a best-effort basis. It may return the latest + // state before the specified timeout (including immediately), meaning even an + // immediate response is no guarantee that the operation is done. + WaitOperation(context.Context, *connect.Request[longrunningpb.WaitOperationRequest]) (*connect.Response[longrunningpb.Operation], error) +} + +// NewOperationsClient constructs a client for the google.longrunning.Operations service. By +// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, +// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the +// connect.WithGRPC() or connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewOperationsClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) OperationsClient { + baseURL = strings.TrimRight(baseURL, "/") + operationsMethods := longrunningpb.File_google_longrunning_operations_proto.Services().ByName("Operations").Methods() + return &operationsClient{ + listOperations: connect.NewClient[longrunningpb.ListOperationsRequest, longrunningpb.ListOperationsResponse]( + httpClient, + baseURL+OperationsListOperationsProcedure, + connect.WithSchema(operationsMethods.ByName("ListOperations")), + connect.WithClientOptions(opts...), + ), + getOperation: connect.NewClient[longrunningpb.GetOperationRequest, longrunningpb.Operation]( + httpClient, + baseURL+OperationsGetOperationProcedure, + connect.WithSchema(operationsMethods.ByName("GetOperation")), + connect.WithClientOptions(opts...), + ), + deleteOperation: connect.NewClient[longrunningpb.DeleteOperationRequest, emptypb.Empty]( + httpClient, + baseURL+OperationsDeleteOperationProcedure, + connect.WithSchema(operationsMethods.ByName("DeleteOperation")), + connect.WithClientOptions(opts...), + ), + cancelOperation: connect.NewClient[longrunningpb.CancelOperationRequest, emptypb.Empty]( + httpClient, + baseURL+OperationsCancelOperationProcedure, + connect.WithSchema(operationsMethods.ByName("CancelOperation")), + connect.WithClientOptions(opts...), + ), + waitOperation: connect.NewClient[longrunningpb.WaitOperationRequest, longrunningpb.Operation]( + httpClient, + baseURL+OperationsWaitOperationProcedure, + connect.WithSchema(operationsMethods.ByName("WaitOperation")), + connect.WithClientOptions(opts...), + ), + } +} + +// operationsClient implements OperationsClient. +type operationsClient struct { + listOperations *connect.Client[longrunningpb.ListOperationsRequest, longrunningpb.ListOperationsResponse] + getOperation *connect.Client[longrunningpb.GetOperationRequest, longrunningpb.Operation] + deleteOperation *connect.Client[longrunningpb.DeleteOperationRequest, emptypb.Empty] + cancelOperation *connect.Client[longrunningpb.CancelOperationRequest, emptypb.Empty] + waitOperation *connect.Client[longrunningpb.WaitOperationRequest, longrunningpb.Operation] +} + +// ListOperations calls google.longrunning.Operations.ListOperations. +func (c *operationsClient) ListOperations(ctx context.Context, req *connect.Request[longrunningpb.ListOperationsRequest]) (*connect.Response[longrunningpb.ListOperationsResponse], error) { + return c.listOperations.CallUnary(ctx, req) +} + +// GetOperation calls google.longrunning.Operations.GetOperation. +func (c *operationsClient) GetOperation(ctx context.Context, req *connect.Request[longrunningpb.GetOperationRequest]) (*connect.Response[longrunningpb.Operation], error) { + return c.getOperation.CallUnary(ctx, req) +} + +// DeleteOperation calls google.longrunning.Operations.DeleteOperation. +func (c *operationsClient) DeleteOperation(ctx context.Context, req *connect.Request[longrunningpb.DeleteOperationRequest]) (*connect.Response[emptypb.Empty], error) { + return c.deleteOperation.CallUnary(ctx, req) +} + +// CancelOperation calls google.longrunning.Operations.CancelOperation. +func (c *operationsClient) CancelOperation(ctx context.Context, req *connect.Request[longrunningpb.CancelOperationRequest]) (*connect.Response[emptypb.Empty], error) { + return c.cancelOperation.CallUnary(ctx, req) +} + +// WaitOperation calls google.longrunning.Operations.WaitOperation. +func (c *operationsClient) WaitOperation(ctx context.Context, req *connect.Request[longrunningpb.WaitOperationRequest]) (*connect.Response[longrunningpb.Operation], error) { + return c.waitOperation.CallUnary(ctx, req) +} + +// OperationsHandler is an implementation of the google.longrunning.Operations service. +type OperationsHandler interface { + // Lists operations that match the specified filter in the request. If the + // server doesn't support this method, it returns `UNIMPLEMENTED`. + ListOperations(context.Context, *connect.Request[longrunningpb.ListOperationsRequest]) (*connect.Response[longrunningpb.ListOperationsResponse], error) + // Gets the latest state of a long-running operation. Clients can use this + // method to poll the operation result at intervals as recommended by the API + // service. + GetOperation(context.Context, *connect.Request[longrunningpb.GetOperationRequest]) (*connect.Response[longrunningpb.Operation], error) + // Deletes a long-running operation. This method indicates that the client is + // no longer interested in the operation result. It does not cancel the + // operation. If the server doesn't support this method, it returns + // `google.rpc.Code.UNIMPLEMENTED`. + DeleteOperation(context.Context, *connect.Request[longrunningpb.DeleteOperationRequest]) (*connect.Response[emptypb.Empty], error) + // Starts asynchronous cancellation on a long-running operation. The server + // makes a best effort to cancel the operation, but success is not + // guaranteed. If the server doesn't support this method, it returns + // `google.rpc.Code.UNIMPLEMENTED`. Clients can use + // [Operations.GetOperation][google.longrunning.Operations.GetOperation] or + // other methods to check whether the cancellation succeeded or whether the + // operation completed despite cancellation. On successful cancellation, + // the operation is not deleted; instead, it becomes an operation with + // an [Operation.error][google.longrunning.Operation.error] value with a + // [google.rpc.Status.code][google.rpc.Status.code] of `1`, corresponding to + // `Code.CANCELLED`. + CancelOperation(context.Context, *connect.Request[longrunningpb.CancelOperationRequest]) (*connect.Response[emptypb.Empty], error) + // Waits until the specified long-running operation is done or reaches at most + // a specified timeout, returning the latest state. If the operation is + // already done, the latest state is immediately returned. If the timeout + // specified is greater than the default HTTP/RPC timeout, the HTTP/RPC + // timeout is used. If the server does not support this method, it returns + // `google.rpc.Code.UNIMPLEMENTED`. + // Note that this method is on a best-effort basis. It may return the latest + // state before the specified timeout (including immediately), meaning even an + // immediate response is no guarantee that the operation is done. + WaitOperation(context.Context, *connect.Request[longrunningpb.WaitOperationRequest]) (*connect.Response[longrunningpb.Operation], error) +} + +// NewOperationsHandler builds an HTTP handler from the service implementation. It returns the path +// on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewOperationsHandler(svc OperationsHandler, opts ...connect.HandlerOption) (string, http.Handler) { + operationsMethods := longrunningpb.File_google_longrunning_operations_proto.Services().ByName("Operations").Methods() + operationsListOperationsHandler := connect.NewUnaryHandler( + OperationsListOperationsProcedure, + svc.ListOperations, + connect.WithSchema(operationsMethods.ByName("ListOperations")), + connect.WithHandlerOptions(opts...), + ) + operationsGetOperationHandler := connect.NewUnaryHandler( + OperationsGetOperationProcedure, + svc.GetOperation, + connect.WithSchema(operationsMethods.ByName("GetOperation")), + connect.WithHandlerOptions(opts...), + ) + operationsDeleteOperationHandler := connect.NewUnaryHandler( + OperationsDeleteOperationProcedure, + svc.DeleteOperation, + connect.WithSchema(operationsMethods.ByName("DeleteOperation")), + connect.WithHandlerOptions(opts...), + ) + operationsCancelOperationHandler := connect.NewUnaryHandler( + OperationsCancelOperationProcedure, + svc.CancelOperation, + connect.WithSchema(operationsMethods.ByName("CancelOperation")), + connect.WithHandlerOptions(opts...), + ) + operationsWaitOperationHandler := connect.NewUnaryHandler( + OperationsWaitOperationProcedure, + svc.WaitOperation, + connect.WithSchema(operationsMethods.ByName("WaitOperation")), + connect.WithHandlerOptions(opts...), + ) + return "/google.longrunning.Operations/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case OperationsListOperationsProcedure: + operationsListOperationsHandler.ServeHTTP(w, r) + case OperationsGetOperationProcedure: + operationsGetOperationHandler.ServeHTTP(w, r) + case OperationsDeleteOperationProcedure: + operationsDeleteOperationHandler.ServeHTTP(w, r) + case OperationsCancelOperationProcedure: + operationsCancelOperationHandler.ServeHTTP(w, r) + case OperationsWaitOperationProcedure: + operationsWaitOperationHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedOperationsHandler returns CodeUnimplemented from all methods. +type UnimplementedOperationsHandler struct{} + +func (UnimplementedOperationsHandler) ListOperations(context.Context, *connect.Request[longrunningpb.ListOperationsRequest]) (*connect.Response[longrunningpb.ListOperationsResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("google.longrunning.Operations.ListOperations is not implemented")) +} + +func (UnimplementedOperationsHandler) GetOperation(context.Context, *connect.Request[longrunningpb.GetOperationRequest]) (*connect.Response[longrunningpb.Operation], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("google.longrunning.Operations.GetOperation is not implemented")) +} + +func (UnimplementedOperationsHandler) DeleteOperation(context.Context, *connect.Request[longrunningpb.DeleteOperationRequest]) (*connect.Response[emptypb.Empty], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("google.longrunning.Operations.DeleteOperation is not implemented")) +} + +func (UnimplementedOperationsHandler) CancelOperation(context.Context, *connect.Request[longrunningpb.CancelOperationRequest]) (*connect.Response[emptypb.Empty], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("google.longrunning.Operations.CancelOperation is not implemented")) +} + +func (UnimplementedOperationsHandler) WaitOperation(context.Context, *connect.Request[longrunningpb.WaitOperationRequest]) (*connect.Response[longrunningpb.Operation], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("google.longrunning.Operations.WaitOperation is not implemented")) +} diff --git a/gen/go/lapp/web/v1/web.pb.go b/gen/go/lapp/web/v1/web.pb.go index 98349a8..f75bfa1 100644 --- a/gen/go/lapp/web/v1/web.pb.go +++ b/gen/go/lapp/web/v1/web.pb.go @@ -7,6 +7,7 @@ package webv1 import ( + longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" @@ -561,6 +562,50 @@ func (x *ImportRun) GetError() *ImportRunError { return nil } +type ImportRunMetadata struct { + state protoimpl.MessageState `protogen:"open.v1"` + ImportRun *ImportRun `protobuf:"bytes,1,opt,name=import_run,json=importRun,proto3" json:"import_run,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ImportRunMetadata) Reset() { + *x = ImportRunMetadata{} + mi := &file_lapp_web_v1_web_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ImportRunMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ImportRunMetadata) ProtoMessage() {} + +func (x *ImportRunMetadata) ProtoReflect() protoreflect.Message { + mi := &file_lapp_web_v1_web_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ImportRunMetadata.ProtoReflect.Descriptor instead. +func (*ImportRunMetadata) Descriptor() ([]byte, []int) { + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{3} +} + +func (x *ImportRunMetadata) GetImportRun() *ImportRun { + if x != nil { + return x.ImportRun + } + return nil +} + type ImportRunError struct { state protoimpl.MessageState `protogen:"open.v1"` Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"` @@ -571,7 +616,7 @@ type ImportRunError struct { func (x *ImportRunError) Reset() { *x = ImportRunError{} - mi := &file_lapp_web_v1_web_proto_msgTypes[3] + mi := &file_lapp_web_v1_web_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -583,7 +628,7 @@ func (x *ImportRunError) String() string { func (*ImportRunError) ProtoMessage() {} func (x *ImportRunError) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[3] + mi := &file_lapp_web_v1_web_proto_msgTypes[4] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -596,7 +641,7 @@ func (x *ImportRunError) ProtoReflect() protoreflect.Message { // Deprecated: Use ImportRunError.ProtoReflect.Descriptor instead. func (*ImportRunError) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{3} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{4} } func (x *ImportRunError) GetCode() string { @@ -636,7 +681,7 @@ type DiscoveryRun struct { func (x *DiscoveryRun) Reset() { *x = DiscoveryRun{} - mi := &file_lapp_web_v1_web_proto_msgTypes[4] + mi := &file_lapp_web_v1_web_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -648,7 +693,7 @@ func (x *DiscoveryRun) String() string { func (*DiscoveryRun) ProtoMessage() {} func (x *DiscoveryRun) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[4] + mi := &file_lapp_web_v1_web_proto_msgTypes[5] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -661,7 +706,7 @@ func (x *DiscoveryRun) ProtoReflect() protoreflect.Message { // Deprecated: Use DiscoveryRun.ProtoReflect.Descriptor instead. func (*DiscoveryRun) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{4} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{5} } func (x *DiscoveryRun) GetName() string { @@ -757,6 +802,50 @@ func (x *DiscoveryRun) GetError() *DiscoveryRunError { return nil } +type DiscoveryRunMetadata struct { + state protoimpl.MessageState `protogen:"open.v1"` + DiscoveryRun *DiscoveryRun `protobuf:"bytes,1,opt,name=discovery_run,json=discoveryRun,proto3" json:"discovery_run,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DiscoveryRunMetadata) Reset() { + *x = DiscoveryRunMetadata{} + mi := &file_lapp_web_v1_web_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DiscoveryRunMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DiscoveryRunMetadata) ProtoMessage() {} + +func (x *DiscoveryRunMetadata) ProtoReflect() protoreflect.Message { + mi := &file_lapp_web_v1_web_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DiscoveryRunMetadata.ProtoReflect.Descriptor instead. +func (*DiscoveryRunMetadata) Descriptor() ([]byte, []int) { + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{6} +} + +func (x *DiscoveryRunMetadata) GetDiscoveryRun() *DiscoveryRun { + if x != nil { + return x.DiscoveryRun + } + return nil +} + type DiscoveryRunProgress struct { state protoimpl.MessageState `protogen:"open.v1"` Step DiscoveryStep `protobuf:"varint,1,opt,name=step,proto3,enum=lapp.web.v1.DiscoveryStep" json:"step,omitempty"` @@ -767,7 +856,7 @@ type DiscoveryRunProgress struct { func (x *DiscoveryRunProgress) Reset() { *x = DiscoveryRunProgress{} - mi := &file_lapp_web_v1_web_proto_msgTypes[5] + mi := &file_lapp_web_v1_web_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -779,7 +868,7 @@ func (x *DiscoveryRunProgress) String() string { func (*DiscoveryRunProgress) ProtoMessage() {} func (x *DiscoveryRunProgress) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[5] + mi := &file_lapp_web_v1_web_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -792,7 +881,7 @@ func (x *DiscoveryRunProgress) ProtoReflect() protoreflect.Message { // Deprecated: Use DiscoveryRunProgress.ProtoReflect.Descriptor instead. func (*DiscoveryRunProgress) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{5} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{7} } func (x *DiscoveryRunProgress) GetStep() DiscoveryStep { @@ -824,7 +913,7 @@ type DiscoveryLabelBatchProgress struct { func (x *DiscoveryLabelBatchProgress) Reset() { *x = DiscoveryLabelBatchProgress{} - mi := &file_lapp_web_v1_web_proto_msgTypes[6] + mi := &file_lapp_web_v1_web_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -836,7 +925,7 @@ func (x *DiscoveryLabelBatchProgress) String() string { func (*DiscoveryLabelBatchProgress) ProtoMessage() {} func (x *DiscoveryLabelBatchProgress) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[6] + mi := &file_lapp_web_v1_web_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -849,7 +938,7 @@ func (x *DiscoveryLabelBatchProgress) ProtoReflect() protoreflect.Message { // Deprecated: Use DiscoveryLabelBatchProgress.ProtoReflect.Descriptor instead. func (*DiscoveryLabelBatchProgress) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{6} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{8} } func (x *DiscoveryLabelBatchProgress) GetEvent() string { @@ -912,7 +1001,7 @@ type DiscoveryRunError struct { func (x *DiscoveryRunError) Reset() { *x = DiscoveryRunError{} - mi := &file_lapp_web_v1_web_proto_msgTypes[7] + mi := &file_lapp_web_v1_web_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -924,7 +1013,7 @@ func (x *DiscoveryRunError) String() string { func (*DiscoveryRunError) ProtoMessage() {} func (x *DiscoveryRunError) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[7] + mi := &file_lapp_web_v1_web_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -937,7 +1026,7 @@ func (x *DiscoveryRunError) ProtoReflect() protoreflect.Message { // Deprecated: Use DiscoveryRunError.ProtoReflect.Descriptor instead. func (*DiscoveryRunError) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{7} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{9} } func (x *DiscoveryRunError) GetCode() string { @@ -979,7 +1068,7 @@ type Pattern struct { func (x *Pattern) Reset() { *x = Pattern{} - mi := &file_lapp_web_v1_web_proto_msgTypes[8] + mi := &file_lapp_web_v1_web_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -991,7 +1080,7 @@ func (x *Pattern) String() string { func (*Pattern) ProtoMessage() {} func (x *Pattern) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[8] + mi := &file_lapp_web_v1_web_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1004,7 +1093,7 @@ func (x *Pattern) ProtoReflect() protoreflect.Message { // Deprecated: Use Pattern.ProtoReflect.Descriptor instead. func (*Pattern) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{8} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{10} } func (x *Pattern) GetName() string { @@ -1087,7 +1176,7 @@ type LineRef struct { func (x *LineRef) Reset() { *x = LineRef{} - mi := &file_lapp_web_v1_web_proto_msgTypes[9] + mi := &file_lapp_web_v1_web_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1099,7 +1188,7 @@ func (x *LineRef) String() string { func (*LineRef) ProtoMessage() {} func (x *LineRef) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[9] + mi := &file_lapp_web_v1_web_proto_msgTypes[11] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1112,7 +1201,7 @@ func (x *LineRef) ProtoReflect() protoreflect.Message { // Deprecated: Use LineRef.ProtoReflect.Descriptor instead. func (*LineRef) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{9} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{11} } func (x *LineRef) GetFileName() string { @@ -1138,7 +1227,7 @@ type ErrorPattern struct { func (x *ErrorPattern) Reset() { *x = ErrorPattern{} - mi := &file_lapp_web_v1_web_proto_msgTypes[10] + mi := &file_lapp_web_v1_web_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1150,7 +1239,7 @@ func (x *ErrorPattern) String() string { func (*ErrorPattern) ProtoMessage() {} func (x *ErrorPattern) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[10] + mi := &file_lapp_web_v1_web_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1163,7 +1252,7 @@ func (x *ErrorPattern) ProtoReflect() protoreflect.Message { // Deprecated: Use ErrorPattern.ProtoReflect.Descriptor instead. func (*ErrorPattern) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{10} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{12} } func (x *ErrorPattern) GetPattern() *Pattern { @@ -1184,7 +1273,7 @@ type UnmatchedErrorLine struct { func (x *UnmatchedErrorLine) Reset() { *x = UnmatchedErrorLine{} - mi := &file_lapp_web_v1_web_proto_msgTypes[11] + mi := &file_lapp_web_v1_web_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1196,7 +1285,7 @@ func (x *UnmatchedErrorLine) String() string { func (*UnmatchedErrorLine) ProtoMessage() {} func (x *UnmatchedErrorLine) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[11] + mi := &file_lapp_web_v1_web_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1209,7 +1298,7 @@ func (x *UnmatchedErrorLine) ProtoReflect() protoreflect.Message { // Deprecated: Use UnmatchedErrorLine.ProtoReflect.Descriptor instead. func (*UnmatchedErrorLine) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{11} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{13} } func (x *UnmatchedErrorLine) GetFileName() string { @@ -1241,7 +1330,7 @@ type ListWorkspacesRequest struct { func (x *ListWorkspacesRequest) Reset() { *x = ListWorkspacesRequest{} - mi := &file_lapp_web_v1_web_proto_msgTypes[12] + mi := &file_lapp_web_v1_web_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1253,7 +1342,7 @@ func (x *ListWorkspacesRequest) String() string { func (*ListWorkspacesRequest) ProtoMessage() {} func (x *ListWorkspacesRequest) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[12] + mi := &file_lapp_web_v1_web_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1266,7 +1355,7 @@ func (x *ListWorkspacesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkspacesRequest.ProtoReflect.Descriptor instead. func (*ListWorkspacesRequest) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{12} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{14} } type ListWorkspacesResponse struct { @@ -1278,7 +1367,7 @@ type ListWorkspacesResponse struct { func (x *ListWorkspacesResponse) Reset() { *x = ListWorkspacesResponse{} - mi := &file_lapp_web_v1_web_proto_msgTypes[13] + mi := &file_lapp_web_v1_web_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1290,7 +1379,7 @@ func (x *ListWorkspacesResponse) String() string { func (*ListWorkspacesResponse) ProtoMessage() {} func (x *ListWorkspacesResponse) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[13] + mi := &file_lapp_web_v1_web_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1303,7 +1392,7 @@ func (x *ListWorkspacesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkspacesResponse.ProtoReflect.Descriptor instead. func (*ListWorkspacesResponse) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{13} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{15} } func (x *ListWorkspacesResponse) GetWorkspaces() []*Workspace { @@ -1322,7 +1411,7 @@ type GetWorkspaceRequest struct { func (x *GetWorkspaceRequest) Reset() { *x = GetWorkspaceRequest{} - mi := &file_lapp_web_v1_web_proto_msgTypes[14] + mi := &file_lapp_web_v1_web_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1334,7 +1423,7 @@ func (x *GetWorkspaceRequest) String() string { func (*GetWorkspaceRequest) ProtoMessage() {} func (x *GetWorkspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[14] + mi := &file_lapp_web_v1_web_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1347,7 +1436,7 @@ func (x *GetWorkspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkspaceRequest.ProtoReflect.Descriptor instead. func (*GetWorkspaceRequest) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{14} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{16} } func (x *GetWorkspaceRequest) GetName() string { @@ -1366,7 +1455,7 @@ type GetWorkspaceResponse struct { func (x *GetWorkspaceResponse) Reset() { *x = GetWorkspaceResponse{} - mi := &file_lapp_web_v1_web_proto_msgTypes[15] + mi := &file_lapp_web_v1_web_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1378,7 +1467,7 @@ func (x *GetWorkspaceResponse) String() string { func (*GetWorkspaceResponse) ProtoMessage() {} func (x *GetWorkspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[15] + mi := &file_lapp_web_v1_web_proto_msgTypes[17] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1391,7 +1480,7 @@ func (x *GetWorkspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkspaceResponse.ProtoReflect.Descriptor instead. func (*GetWorkspaceResponse) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{15} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{17} } func (x *GetWorkspaceResponse) GetWorkspace() *Workspace { @@ -1410,7 +1499,7 @@ type CreateWorkspaceRequest struct { func (x *CreateWorkspaceRequest) Reset() { *x = CreateWorkspaceRequest{} - mi := &file_lapp_web_v1_web_proto_msgTypes[16] + mi := &file_lapp_web_v1_web_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1422,7 +1511,7 @@ func (x *CreateWorkspaceRequest) String() string { func (*CreateWorkspaceRequest) ProtoMessage() {} func (x *CreateWorkspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[16] + mi := &file_lapp_web_v1_web_proto_msgTypes[18] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1435,7 +1524,7 @@ func (x *CreateWorkspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateWorkspaceRequest.ProtoReflect.Descriptor instead. func (*CreateWorkspaceRequest) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{16} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{18} } func (x *CreateWorkspaceRequest) GetWorkspaceId() string { @@ -1454,7 +1543,7 @@ type CreateWorkspaceResponse struct { func (x *CreateWorkspaceResponse) Reset() { *x = CreateWorkspaceResponse{} - mi := &file_lapp_web_v1_web_proto_msgTypes[17] + mi := &file_lapp_web_v1_web_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1466,7 +1555,7 @@ func (x *CreateWorkspaceResponse) String() string { func (*CreateWorkspaceResponse) ProtoMessage() {} func (x *CreateWorkspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[17] + mi := &file_lapp_web_v1_web_proto_msgTypes[19] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1479,7 +1568,7 @@ func (x *CreateWorkspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateWorkspaceResponse.ProtoReflect.Descriptor instead. func (*CreateWorkspaceResponse) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{17} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{19} } func (x *CreateWorkspaceResponse) GetWorkspace() *Workspace { @@ -1498,7 +1587,7 @@ type DeleteWorkspaceRequest struct { func (x *DeleteWorkspaceRequest) Reset() { *x = DeleteWorkspaceRequest{} - mi := &file_lapp_web_v1_web_proto_msgTypes[18] + mi := &file_lapp_web_v1_web_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1510,7 +1599,7 @@ func (x *DeleteWorkspaceRequest) String() string { func (*DeleteWorkspaceRequest) ProtoMessage() {} func (x *DeleteWorkspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[18] + mi := &file_lapp_web_v1_web_proto_msgTypes[20] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1523,7 +1612,7 @@ func (x *DeleteWorkspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteWorkspaceRequest.ProtoReflect.Descriptor instead. func (*DeleteWorkspaceRequest) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{18} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{20} } func (x *DeleteWorkspaceRequest) GetName() string { @@ -1541,7 +1630,7 @@ type DeleteWorkspaceResponse struct { func (x *DeleteWorkspaceResponse) Reset() { *x = DeleteWorkspaceResponse{} - mi := &file_lapp_web_v1_web_proto_msgTypes[19] + mi := &file_lapp_web_v1_web_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1553,7 +1642,7 @@ func (x *DeleteWorkspaceResponse) String() string { func (*DeleteWorkspaceResponse) ProtoMessage() {} func (x *DeleteWorkspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[19] + mi := &file_lapp_web_v1_web_proto_msgTypes[21] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1566,7 +1655,7 @@ func (x *DeleteWorkspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteWorkspaceResponse.ProtoReflect.Descriptor instead. func (*DeleteWorkspaceResponse) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{19} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{21} } type ListLogFilesRequest struct { @@ -1578,7 +1667,7 @@ type ListLogFilesRequest struct { func (x *ListLogFilesRequest) Reset() { *x = ListLogFilesRequest{} - mi := &file_lapp_web_v1_web_proto_msgTypes[20] + mi := &file_lapp_web_v1_web_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1590,7 +1679,7 @@ func (x *ListLogFilesRequest) String() string { func (*ListLogFilesRequest) ProtoMessage() {} func (x *ListLogFilesRequest) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[20] + mi := &file_lapp_web_v1_web_proto_msgTypes[22] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1603,7 +1692,7 @@ func (x *ListLogFilesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListLogFilesRequest.ProtoReflect.Descriptor instead. func (*ListLogFilesRequest) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{20} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{22} } func (x *ListLogFilesRequest) GetParent() string { @@ -1622,7 +1711,7 @@ type ListLogFilesResponse struct { func (x *ListLogFilesResponse) Reset() { *x = ListLogFilesResponse{} - mi := &file_lapp_web_v1_web_proto_msgTypes[21] + mi := &file_lapp_web_v1_web_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1634,7 +1723,7 @@ func (x *ListLogFilesResponse) String() string { func (*ListLogFilesResponse) ProtoMessage() {} func (x *ListLogFilesResponse) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[21] + mi := &file_lapp_web_v1_web_proto_msgTypes[23] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1647,7 +1736,7 @@ func (x *ListLogFilesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListLogFilesResponse.ProtoReflect.Descriptor instead. func (*ListLogFilesResponse) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{21} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{23} } func (x *ListLogFilesResponse) GetLogFiles() []*LogFile { @@ -1668,7 +1757,7 @@ type UploadLogFileRequest struct { func (x *UploadLogFileRequest) Reset() { *x = UploadLogFileRequest{} - mi := &file_lapp_web_v1_web_proto_msgTypes[22] + mi := &file_lapp_web_v1_web_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1680,7 +1769,7 @@ func (x *UploadLogFileRequest) String() string { func (*UploadLogFileRequest) ProtoMessage() {} func (x *UploadLogFileRequest) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[22] + mi := &file_lapp_web_v1_web_proto_msgTypes[24] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1693,7 +1782,7 @@ func (x *UploadLogFileRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UploadLogFileRequest.ProtoReflect.Descriptor instead. func (*UploadLogFileRequest) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{22} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{24} } func (x *UploadLogFileRequest) GetParent() string { @@ -1726,7 +1815,7 @@ type UploadLogFileResponse struct { func (x *UploadLogFileResponse) Reset() { *x = UploadLogFileResponse{} - mi := &file_lapp_web_v1_web_proto_msgTypes[23] + mi := &file_lapp_web_v1_web_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1738,7 +1827,7 @@ func (x *UploadLogFileResponse) String() string { func (*UploadLogFileResponse) ProtoMessage() {} func (x *UploadLogFileResponse) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[23] + mi := &file_lapp_web_v1_web_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1751,7 +1840,7 @@ func (x *UploadLogFileResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UploadLogFileResponse.ProtoReflect.Descriptor instead. func (*UploadLogFileResponse) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{23} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{25} } func (x *UploadLogFileResponse) GetLogFile() *LogFile { @@ -1770,7 +1859,7 @@ type DeleteLogFileRequest struct { func (x *DeleteLogFileRequest) Reset() { *x = DeleteLogFileRequest{} - mi := &file_lapp_web_v1_web_proto_msgTypes[24] + mi := &file_lapp_web_v1_web_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1782,7 +1871,7 @@ func (x *DeleteLogFileRequest) String() string { func (*DeleteLogFileRequest) ProtoMessage() {} func (x *DeleteLogFileRequest) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[24] + mi := &file_lapp_web_v1_web_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1795,7 +1884,7 @@ func (x *DeleteLogFileRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteLogFileRequest.ProtoReflect.Descriptor instead. func (*DeleteLogFileRequest) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{24} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{26} } func (x *DeleteLogFileRequest) GetName() string { @@ -1813,7 +1902,7 @@ type DeleteLogFileResponse struct { func (x *DeleteLogFileResponse) Reset() { *x = DeleteLogFileResponse{} - mi := &file_lapp_web_v1_web_proto_msgTypes[25] + mi := &file_lapp_web_v1_web_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1825,7 +1914,7 @@ func (x *DeleteLogFileResponse) String() string { func (*DeleteLogFileResponse) ProtoMessage() {} func (x *DeleteLogFileResponse) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[25] + mi := &file_lapp_web_v1_web_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1838,7 +1927,7 @@ func (x *DeleteLogFileResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteLogFileResponse.ProtoReflect.Descriptor instead. func (*DeleteLogFileResponse) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{25} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{27} } type CreateImportRunRequest struct { @@ -1855,7 +1944,7 @@ type CreateImportRunRequest struct { func (x *CreateImportRunRequest) Reset() { *x = CreateImportRunRequest{} - mi := &file_lapp_web_v1_web_proto_msgTypes[26] + mi := &file_lapp_web_v1_web_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1867,7 +1956,7 @@ func (x *CreateImportRunRequest) String() string { func (*CreateImportRunRequest) ProtoMessage() {} func (x *CreateImportRunRequest) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[26] + mi := &file_lapp_web_v1_web_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1880,7 +1969,7 @@ func (x *CreateImportRunRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateImportRunRequest.ProtoReflect.Descriptor instead. func (*CreateImportRunRequest) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{26} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{28} } func (x *CreateImportRunRequest) GetParent() string { @@ -1925,50 +2014,6 @@ func (x *CreateImportRunRequest) GetLimit() int32 { return 0 } -type CreateImportRunResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - ImportRun *ImportRun `protobuf:"bytes,1,opt,name=import_run,json=importRun,proto3" json:"import_run,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *CreateImportRunResponse) Reset() { - *x = CreateImportRunResponse{} - mi := &file_lapp_web_v1_web_proto_msgTypes[27] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *CreateImportRunResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateImportRunResponse) ProtoMessage() {} - -func (x *CreateImportRunResponse) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[27] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateImportRunResponse.ProtoReflect.Descriptor instead. -func (*CreateImportRunResponse) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{27} -} - -func (x *CreateImportRunResponse) GetImportRun() *ImportRun { - if x != nil { - return x.ImportRun - } - return nil -} - type GetImportRunRequest struct { state protoimpl.MessageState `protogen:"open.v1"` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` @@ -1978,7 +2023,7 @@ type GetImportRunRequest struct { func (x *GetImportRunRequest) Reset() { *x = GetImportRunRequest{} - mi := &file_lapp_web_v1_web_proto_msgTypes[28] + mi := &file_lapp_web_v1_web_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1990,7 +2035,7 @@ func (x *GetImportRunRequest) String() string { func (*GetImportRunRequest) ProtoMessage() {} func (x *GetImportRunRequest) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[28] + mi := &file_lapp_web_v1_web_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2003,7 +2048,7 @@ func (x *GetImportRunRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetImportRunRequest.ProtoReflect.Descriptor instead. func (*GetImportRunRequest) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{28} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{29} } func (x *GetImportRunRequest) GetName() string { @@ -2022,7 +2067,7 @@ type GetImportRunResponse struct { func (x *GetImportRunResponse) Reset() { *x = GetImportRunResponse{} - mi := &file_lapp_web_v1_web_proto_msgTypes[29] + mi := &file_lapp_web_v1_web_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2034,7 +2079,7 @@ func (x *GetImportRunResponse) String() string { func (*GetImportRunResponse) ProtoMessage() {} func (x *GetImportRunResponse) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[29] + mi := &file_lapp_web_v1_web_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2047,7 +2092,7 @@ func (x *GetImportRunResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetImportRunResponse.ProtoReflect.Descriptor instead. func (*GetImportRunResponse) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{29} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{30} } func (x *GetImportRunResponse) GetImportRun() *ImportRun { @@ -2066,7 +2111,7 @@ type ListImportRunsRequest struct { func (x *ListImportRunsRequest) Reset() { *x = ListImportRunsRequest{} - mi := &file_lapp_web_v1_web_proto_msgTypes[30] + mi := &file_lapp_web_v1_web_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2078,7 +2123,7 @@ func (x *ListImportRunsRequest) String() string { func (*ListImportRunsRequest) ProtoMessage() {} func (x *ListImportRunsRequest) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[30] + mi := &file_lapp_web_v1_web_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2091,7 +2136,7 @@ func (x *ListImportRunsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListImportRunsRequest.ProtoReflect.Descriptor instead. func (*ListImportRunsRequest) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{30} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{31} } func (x *ListImportRunsRequest) GetParent() string { @@ -2110,7 +2155,7 @@ type ListImportRunsResponse struct { func (x *ListImportRunsResponse) Reset() { *x = ListImportRunsResponse{} - mi := &file_lapp_web_v1_web_proto_msgTypes[31] + mi := &file_lapp_web_v1_web_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2122,7 +2167,7 @@ func (x *ListImportRunsResponse) String() string { func (*ListImportRunsResponse) ProtoMessage() {} func (x *ListImportRunsResponse) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[31] + mi := &file_lapp_web_v1_web_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2135,7 +2180,7 @@ func (x *ListImportRunsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListImportRunsResponse.ProtoReflect.Descriptor instead. func (*ListImportRunsResponse) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{31} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{32} } func (x *ListImportRunsResponse) GetImportRuns() []*ImportRun { @@ -2153,7 +2198,7 @@ type ListRecentImportQueriesRequest struct { func (x *ListRecentImportQueriesRequest) Reset() { *x = ListRecentImportQueriesRequest{} - mi := &file_lapp_web_v1_web_proto_msgTypes[32] + mi := &file_lapp_web_v1_web_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2165,7 +2210,7 @@ func (x *ListRecentImportQueriesRequest) String() string { func (*ListRecentImportQueriesRequest) ProtoMessage() {} func (x *ListRecentImportQueriesRequest) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[32] + mi := &file_lapp_web_v1_web_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2178,7 +2223,7 @@ func (x *ListRecentImportQueriesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListRecentImportQueriesRequest.ProtoReflect.Descriptor instead. func (*ListRecentImportQueriesRequest) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{32} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{33} } type RecentImportQuery struct { @@ -2192,7 +2237,7 @@ type RecentImportQuery struct { func (x *RecentImportQuery) Reset() { *x = RecentImportQuery{} - mi := &file_lapp_web_v1_web_proto_msgTypes[33] + mi := &file_lapp_web_v1_web_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2204,7 +2249,7 @@ func (x *RecentImportQuery) String() string { func (*RecentImportQuery) ProtoMessage() {} func (x *RecentImportQuery) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[33] + mi := &file_lapp_web_v1_web_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2217,7 +2262,7 @@ func (x *RecentImportQuery) ProtoReflect() protoreflect.Message { // Deprecated: Use RecentImportQuery.ProtoReflect.Descriptor instead. func (*RecentImportQuery) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{33} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{34} } func (x *RecentImportQuery) GetProject() string { @@ -2250,7 +2295,7 @@ type ListRecentImportQueriesResponse struct { func (x *ListRecentImportQueriesResponse) Reset() { *x = ListRecentImportQueriesResponse{} - mi := &file_lapp_web_v1_web_proto_msgTypes[34] + mi := &file_lapp_web_v1_web_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2262,7 +2307,7 @@ func (x *ListRecentImportQueriesResponse) String() string { func (*ListRecentImportQueriesResponse) ProtoMessage() {} func (x *ListRecentImportQueriesResponse) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[34] + mi := &file_lapp_web_v1_web_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2275,7 +2320,7 @@ func (x *ListRecentImportQueriesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListRecentImportQueriesResponse.ProtoReflect.Descriptor instead. func (*ListRecentImportQueriesResponse) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{34} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{35} } func (x *ListRecentImportQueriesResponse) GetRecentQueries() []*RecentImportQuery { @@ -2295,7 +2340,7 @@ type CreateDiscoveryRunRequest struct { func (x *CreateDiscoveryRunRequest) Reset() { *x = CreateDiscoveryRunRequest{} - mi := &file_lapp_web_v1_web_proto_msgTypes[35] + mi := &file_lapp_web_v1_web_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2307,7 +2352,7 @@ func (x *CreateDiscoveryRunRequest) String() string { func (*CreateDiscoveryRunRequest) ProtoMessage() {} func (x *CreateDiscoveryRunRequest) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[35] + mi := &file_lapp_web_v1_web_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2320,7 +2365,7 @@ func (x *CreateDiscoveryRunRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateDiscoveryRunRequest.ProtoReflect.Descriptor instead. func (*CreateDiscoveryRunRequest) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{35} + return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{36} } func (x *CreateDiscoveryRunRequest) GetParent() string { @@ -2337,50 +2382,6 @@ func (x *CreateDiscoveryRunRequest) GetModel() string { return "" } -type CreateDiscoveryRunResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - DiscoveryRun *DiscoveryRun `protobuf:"bytes,1,opt,name=discovery_run,json=discoveryRun,proto3" json:"discovery_run,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *CreateDiscoveryRunResponse) Reset() { - *x = CreateDiscoveryRunResponse{} - mi := &file_lapp_web_v1_web_proto_msgTypes[36] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *CreateDiscoveryRunResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateDiscoveryRunResponse) ProtoMessage() {} - -func (x *CreateDiscoveryRunResponse) ProtoReflect() protoreflect.Message { - mi := &file_lapp_web_v1_web_proto_msgTypes[36] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateDiscoveryRunResponse.ProtoReflect.Descriptor instead. -func (*CreateDiscoveryRunResponse) Descriptor() ([]byte, []int) { - return file_lapp_web_v1_web_proto_rawDescGZIP(), []int{36} -} - -func (x *CreateDiscoveryRunResponse) GetDiscoveryRun() *DiscoveryRun { - if x != nil { - return x.DiscoveryRun - } - return nil -} - type GetDiscoveryRunRequest struct { state protoimpl.MessageState `protogen:"open.v1"` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` @@ -2833,7 +2834,7 @@ var File_lapp_web_v1_web_proto protoreflect.FileDescriptor const file_lapp_web_v1_web_proto_rawDesc = "" + "\n" + - "\x15lapp/web/v1/web.proto\x12\vlapp.web.v1\x1a\x1fgoogle/protobuf/timestamp.proto\"\xf2\x02\n" + + "\x15lapp/web/v1/web.proto\x12\vlapp.web.v1\x1a#google/longrunning/operations.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xf2\x02\n" + "\tWorkspace\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12!\n" + "\fworkspace_id\x18\x02 \x01(\tR\vworkspaceId\x124\n" + @@ -2868,7 +2869,10 @@ const file_lapp_web_v1_web_proto_rawDesc = "" + "started_at\x18\r \x01(\v2\x1a.google.protobuf.TimestampR\tstartedAt\x12;\n" + "\vfinished_at\x18\x0e \x01(\v2\x1a.google.protobuf.TimestampR\n" + "finishedAt\x121\n" + - "\x05error\x18\x0f \x01(\v2\x1b.lapp.web.v1.ImportRunErrorR\x05error\">\n" + + "\x05error\x18\x0f \x01(\v2\x1b.lapp.web.v1.ImportRunErrorR\x05error\"J\n" + + "\x11ImportRunMetadata\x125\n" + + "\n" + + "import_run\x18\x01 \x01(\v2\x16.lapp.web.v1.ImportRunR\timportRun\">\n" + "\x0eImportRunError\x12\x12\n" + "\x04code\x18\x01 \x01(\tR\x04code\x12\x18\n" + "\amessage\x18\x02 \x01(\tR\amessage\"\xfa\x04\n" + @@ -2888,7 +2892,9 @@ const file_lapp_web_v1_web_proto_rawDesc = "" + " \x01(\x05R\fpatternCount\x12'\n" + "\x0funmatched_count\x18\v \x01(\x05R\x0eunmatchedCount\x12=\n" + "\bprogress\x18\f \x01(\v2!.lapp.web.v1.DiscoveryRunProgressR\bprogress\x124\n" + - "\x05error\x18\r \x01(\v2\x1e.lapp.web.v1.DiscoveryRunErrorR\x05error\"\x91\x01\n" + + "\x05error\x18\r \x01(\v2\x1e.lapp.web.v1.DiscoveryRunErrorR\x05error\"V\n" + + "\x14DiscoveryRunMetadata\x12>\n" + + "\rdiscovery_run\x18\x01 \x01(\v2\x19.lapp.web.v1.DiscoveryRunR\fdiscoveryRun\"\x91\x01\n" + "\x14DiscoveryRunProgress\x12.\n" + "\x04step\x18\x01 \x01(\x0e2\x1a.lapp.web.v1.DiscoveryStepR\x04step\x12I\n" + "\vlabel_batch\x18\x02 \x01(\v2(.lapp.web.v1.DiscoveryLabelBatchProgressR\n" + @@ -2968,10 +2974,7 @@ const file_lapp_web_v1_web_proto_rawDesc = "" + "\x06filter\x18\x03 \x01(\tR\x06filter\x12.\n" + "\x04from\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\x04from\x12*\n" + "\x02to\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\x02to\x12\x14\n" + - "\x05limit\x18\x06 \x01(\x05R\x05limit\"P\n" + - "\x17CreateImportRunResponse\x125\n" + - "\n" + - "import_run\x18\x01 \x01(\v2\x16.lapp.web.v1.ImportRunR\timportRun\")\n" + + "\x05limit\x18\x06 \x01(\x05R\x05limit\")\n" + "\x13GetImportRunRequest\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\"M\n" + "\x14GetImportRunResponse\x125\n" + @@ -2992,9 +2995,7 @@ const file_lapp_web_v1_web_proto_rawDesc = "" + "\x0erecent_queries\x18\x01 \x03(\v2\x1e.lapp.web.v1.RecentImportQueryR\rrecentQueries\"I\n" + "\x19CreateDiscoveryRunRequest\x12\x16\n" + "\x06parent\x18\x01 \x01(\tR\x06parent\x12\x14\n" + - "\x05model\x18\x02 \x01(\tR\x05model\"\\\n" + - "\x1aCreateDiscoveryRunResponse\x12>\n" + - "\rdiscovery_run\x18\x01 \x01(\v2\x19.lapp.web.v1.DiscoveryRunR\fdiscoveryRun\",\n" + + "\x05model\x18\x02 \x01(\tR\x05model\",\n" + "\x16GetDiscoveryRunRequest\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\"Y\n" + "\x17GetDiscoveryRunResponse\x12>\n" + @@ -3040,7 +3041,7 @@ const file_lapp_web_v1_web_proto_rawDesc = "" + "\x1eDISCOVERY_STEP_MERGING_ENTRIES\x10\x02\x12'\n" + "#DISCOVERY_STEP_DISCOVERING_PATTERNS\x10\x03\x12$\n" + " DISCOVERY_STEP_LABELING_PATTERNS\x10\x04\x12\"\n" + - "\x1eDISCOVERY_STEP_WRITING_RESULTS\x10\x052\xac\f\n" + + "\x1eDISCOVERY_STEP_WRITING_RESULTS\x10\x052\xe8\f\n" + "\x10WorkspaceService\x12Y\n" + "\x0eListWorkspaces\x12\".lapp.web.v1.ListWorkspacesRequest\x1a#.lapp.web.v1.ListWorkspacesResponse\x12S\n" + "\fGetWorkspace\x12 .lapp.web.v1.GetWorkspaceRequest\x1a!.lapp.web.v1.GetWorkspaceResponse\x12\\\n" + @@ -3048,12 +3049,14 @@ const file_lapp_web_v1_web_proto_rawDesc = "" + "\x0fDeleteWorkspace\x12#.lapp.web.v1.DeleteWorkspaceRequest\x1a$.lapp.web.v1.DeleteWorkspaceResponse\x12S\n" + "\fListLogFiles\x12 .lapp.web.v1.ListLogFilesRequest\x1a!.lapp.web.v1.ListLogFilesResponse\x12V\n" + "\rUploadLogFile\x12!.lapp.web.v1.UploadLogFileRequest\x1a\".lapp.web.v1.UploadLogFileResponse\x12V\n" + - "\rDeleteLogFile\x12!.lapp.web.v1.DeleteLogFileRequest\x1a\".lapp.web.v1.DeleteLogFileResponse\x12\\\n" + - "\x0fCreateImportRun\x12#.lapp.web.v1.CreateImportRunRequest\x1a$.lapp.web.v1.CreateImportRunResponse\x12S\n" + + "\rDeleteLogFile\x12!.lapp.web.v1.DeleteLogFileRequest\x1a\".lapp.web.v1.DeleteLogFileResponse\x12x\n" + + "\x0fCreateImportRun\x12#.lapp.web.v1.CreateImportRunRequest\x1a\x1d.google.longrunning.Operation\"!\xcaA\x1e\n" + + "\tImportRun\x12\x11ImportRunMetadata\x12S\n" + "\fGetImportRun\x12 .lapp.web.v1.GetImportRunRequest\x1a!.lapp.web.v1.GetImportRunResponse\x12Y\n" + "\x0eListImportRuns\x12\".lapp.web.v1.ListImportRunsRequest\x1a#.lapp.web.v1.ListImportRunsResponse\x12t\n" + - "\x17ListRecentImportQueries\x12+.lapp.web.v1.ListRecentImportQueriesRequest\x1a,.lapp.web.v1.ListRecentImportQueriesResponse\x12e\n" + - "\x12CreateDiscoveryRun\x12&.lapp.web.v1.CreateDiscoveryRunRequest\x1a'.lapp.web.v1.CreateDiscoveryRunResponse\x12\\\n" + + "\x17ListRecentImportQueries\x12+.lapp.web.v1.ListRecentImportQueriesRequest\x1a,.lapp.web.v1.ListRecentImportQueriesResponse\x12\x84\x01\n" + + "\x12CreateDiscoveryRun\x12&.lapp.web.v1.CreateDiscoveryRunRequest\x1a\x1d.google.longrunning.Operation\"'\xcaA$\n" + + "\fDiscoveryRun\x12\x14DiscoveryRunMetadata\x12\\\n" + "\x0fGetDiscoveryRun\x12#.lapp.web.v1.GetDiscoveryRunRequest\x1a$.lapp.web.v1.GetDiscoveryRunResponse\x12b\n" + "\x11ListDiscoveryRuns\x12%.lapp.web.v1.ListDiscoveryRunsRequest\x1a&.lapp.web.v1.ListDiscoveryRunsResponse\x12S\n" + "\fListPatterns\x12 .lapp.web.v1.ListPatternsRequest\x1a!.lapp.web.v1.ListPatternsResponse\x12M\n" + @@ -3083,40 +3086,40 @@ var file_lapp_web_v1_web_proto_goTypes = []any{ (*Workspace)(nil), // 4: lapp.web.v1.Workspace (*LogFile)(nil), // 5: lapp.web.v1.LogFile (*ImportRun)(nil), // 6: lapp.web.v1.ImportRun - (*ImportRunError)(nil), // 7: lapp.web.v1.ImportRunError - (*DiscoveryRun)(nil), // 8: lapp.web.v1.DiscoveryRun - (*DiscoveryRunProgress)(nil), // 9: lapp.web.v1.DiscoveryRunProgress - (*DiscoveryLabelBatchProgress)(nil), // 10: lapp.web.v1.DiscoveryLabelBatchProgress - (*DiscoveryRunError)(nil), // 11: lapp.web.v1.DiscoveryRunError - (*Pattern)(nil), // 12: lapp.web.v1.Pattern - (*LineRef)(nil), // 13: lapp.web.v1.LineRef - (*ErrorPattern)(nil), // 14: lapp.web.v1.ErrorPattern - (*UnmatchedErrorLine)(nil), // 15: lapp.web.v1.UnmatchedErrorLine - (*ListWorkspacesRequest)(nil), // 16: lapp.web.v1.ListWorkspacesRequest - (*ListWorkspacesResponse)(nil), // 17: lapp.web.v1.ListWorkspacesResponse - (*GetWorkspaceRequest)(nil), // 18: lapp.web.v1.GetWorkspaceRequest - (*GetWorkspaceResponse)(nil), // 19: lapp.web.v1.GetWorkspaceResponse - (*CreateWorkspaceRequest)(nil), // 20: lapp.web.v1.CreateWorkspaceRequest - (*CreateWorkspaceResponse)(nil), // 21: lapp.web.v1.CreateWorkspaceResponse - (*DeleteWorkspaceRequest)(nil), // 22: lapp.web.v1.DeleteWorkspaceRequest - (*DeleteWorkspaceResponse)(nil), // 23: lapp.web.v1.DeleteWorkspaceResponse - (*ListLogFilesRequest)(nil), // 24: lapp.web.v1.ListLogFilesRequest - (*ListLogFilesResponse)(nil), // 25: lapp.web.v1.ListLogFilesResponse - (*UploadLogFileRequest)(nil), // 26: lapp.web.v1.UploadLogFileRequest - (*UploadLogFileResponse)(nil), // 27: lapp.web.v1.UploadLogFileResponse - (*DeleteLogFileRequest)(nil), // 28: lapp.web.v1.DeleteLogFileRequest - (*DeleteLogFileResponse)(nil), // 29: lapp.web.v1.DeleteLogFileResponse - (*CreateImportRunRequest)(nil), // 30: lapp.web.v1.CreateImportRunRequest - (*CreateImportRunResponse)(nil), // 31: lapp.web.v1.CreateImportRunResponse - (*GetImportRunRequest)(nil), // 32: lapp.web.v1.GetImportRunRequest - (*GetImportRunResponse)(nil), // 33: lapp.web.v1.GetImportRunResponse - (*ListImportRunsRequest)(nil), // 34: lapp.web.v1.ListImportRunsRequest - (*ListImportRunsResponse)(nil), // 35: lapp.web.v1.ListImportRunsResponse - (*ListRecentImportQueriesRequest)(nil), // 36: lapp.web.v1.ListRecentImportQueriesRequest - (*RecentImportQuery)(nil), // 37: lapp.web.v1.RecentImportQuery - (*ListRecentImportQueriesResponse)(nil), // 38: lapp.web.v1.ListRecentImportQueriesResponse - (*CreateDiscoveryRunRequest)(nil), // 39: lapp.web.v1.CreateDiscoveryRunRequest - (*CreateDiscoveryRunResponse)(nil), // 40: lapp.web.v1.CreateDiscoveryRunResponse + (*ImportRunMetadata)(nil), // 7: lapp.web.v1.ImportRunMetadata + (*ImportRunError)(nil), // 8: lapp.web.v1.ImportRunError + (*DiscoveryRun)(nil), // 9: lapp.web.v1.DiscoveryRun + (*DiscoveryRunMetadata)(nil), // 10: lapp.web.v1.DiscoveryRunMetadata + (*DiscoveryRunProgress)(nil), // 11: lapp.web.v1.DiscoveryRunProgress + (*DiscoveryLabelBatchProgress)(nil), // 12: lapp.web.v1.DiscoveryLabelBatchProgress + (*DiscoveryRunError)(nil), // 13: lapp.web.v1.DiscoveryRunError + (*Pattern)(nil), // 14: lapp.web.v1.Pattern + (*LineRef)(nil), // 15: lapp.web.v1.LineRef + (*ErrorPattern)(nil), // 16: lapp.web.v1.ErrorPattern + (*UnmatchedErrorLine)(nil), // 17: lapp.web.v1.UnmatchedErrorLine + (*ListWorkspacesRequest)(nil), // 18: lapp.web.v1.ListWorkspacesRequest + (*ListWorkspacesResponse)(nil), // 19: lapp.web.v1.ListWorkspacesResponse + (*GetWorkspaceRequest)(nil), // 20: lapp.web.v1.GetWorkspaceRequest + (*GetWorkspaceResponse)(nil), // 21: lapp.web.v1.GetWorkspaceResponse + (*CreateWorkspaceRequest)(nil), // 22: lapp.web.v1.CreateWorkspaceRequest + (*CreateWorkspaceResponse)(nil), // 23: lapp.web.v1.CreateWorkspaceResponse + (*DeleteWorkspaceRequest)(nil), // 24: lapp.web.v1.DeleteWorkspaceRequest + (*DeleteWorkspaceResponse)(nil), // 25: lapp.web.v1.DeleteWorkspaceResponse + (*ListLogFilesRequest)(nil), // 26: lapp.web.v1.ListLogFilesRequest + (*ListLogFilesResponse)(nil), // 27: lapp.web.v1.ListLogFilesResponse + (*UploadLogFileRequest)(nil), // 28: lapp.web.v1.UploadLogFileRequest + (*UploadLogFileResponse)(nil), // 29: lapp.web.v1.UploadLogFileResponse + (*DeleteLogFileRequest)(nil), // 30: lapp.web.v1.DeleteLogFileRequest + (*DeleteLogFileResponse)(nil), // 31: lapp.web.v1.DeleteLogFileResponse + (*CreateImportRunRequest)(nil), // 32: lapp.web.v1.CreateImportRunRequest + (*GetImportRunRequest)(nil), // 33: lapp.web.v1.GetImportRunRequest + (*GetImportRunResponse)(nil), // 34: lapp.web.v1.GetImportRunResponse + (*ListImportRunsRequest)(nil), // 35: lapp.web.v1.ListImportRunsRequest + (*ListImportRunsResponse)(nil), // 36: lapp.web.v1.ListImportRunsResponse + (*ListRecentImportQueriesRequest)(nil), // 37: lapp.web.v1.ListRecentImportQueriesRequest + (*RecentImportQuery)(nil), // 38: lapp.web.v1.RecentImportQuery + (*ListRecentImportQueriesResponse)(nil), // 39: lapp.web.v1.ListRecentImportQueriesResponse + (*CreateDiscoveryRunRequest)(nil), // 40: lapp.web.v1.CreateDiscoveryRunRequest (*GetDiscoveryRunRequest)(nil), // 41: lapp.web.v1.GetDiscoveryRunRequest (*GetDiscoveryRunResponse)(nil), // 42: lapp.web.v1.GetDiscoveryRunResponse (*ListDiscoveryRunsRequest)(nil), // 43: lapp.web.v1.ListDiscoveryRunsRequest @@ -3128,79 +3131,80 @@ var file_lapp_web_v1_web_proto_goTypes = []any{ (*GetErrorsViewRequest)(nil), // 49: lapp.web.v1.GetErrorsViewRequest (*GetErrorsViewResponse)(nil), // 50: lapp.web.v1.GetErrorsViewResponse (*timestamppb.Timestamp)(nil), // 51: google.protobuf.Timestamp + (*longrunningpb.Operation)(nil), // 52: google.longrunning.Operation } var file_lapp_web_v1_web_proto_depIdxs = []int32{ 0, // 0: lapp.web.v1.Workspace.status:type_name -> lapp.web.v1.WorkspaceStatus - 8, // 1: lapp.web.v1.Workspace.latest_discovery_run:type_name -> lapp.web.v1.DiscoveryRun - 8, // 2: lapp.web.v1.Workspace.latest_successful_discovery_run:type_name -> lapp.web.v1.DiscoveryRun + 9, // 1: lapp.web.v1.Workspace.latest_discovery_run:type_name -> lapp.web.v1.DiscoveryRun + 9, // 2: lapp.web.v1.Workspace.latest_successful_discovery_run:type_name -> lapp.web.v1.DiscoveryRun 51, // 3: lapp.web.v1.LogFile.updated_at:type_name -> google.protobuf.Timestamp 51, // 4: lapp.web.v1.ImportRun.from:type_name -> google.protobuf.Timestamp 51, // 5: lapp.web.v1.ImportRun.to:type_name -> google.protobuf.Timestamp 1, // 6: lapp.web.v1.ImportRun.state:type_name -> lapp.web.v1.ImportRunState 51, // 7: lapp.web.v1.ImportRun.started_at:type_name -> google.protobuf.Timestamp 51, // 8: lapp.web.v1.ImportRun.finished_at:type_name -> google.protobuf.Timestamp - 7, // 9: lapp.web.v1.ImportRun.error:type_name -> lapp.web.v1.ImportRunError - 2, // 10: lapp.web.v1.DiscoveryRun.state:type_name -> lapp.web.v1.DiscoveryRunState - 3, // 11: lapp.web.v1.DiscoveryRun.current_step:type_name -> lapp.web.v1.DiscoveryStep - 51, // 12: lapp.web.v1.DiscoveryRun.started_at:type_name -> google.protobuf.Timestamp - 51, // 13: lapp.web.v1.DiscoveryRun.finished_at:type_name -> google.protobuf.Timestamp - 9, // 14: lapp.web.v1.DiscoveryRun.progress:type_name -> lapp.web.v1.DiscoveryRunProgress - 11, // 15: lapp.web.v1.DiscoveryRun.error:type_name -> lapp.web.v1.DiscoveryRunError - 3, // 16: lapp.web.v1.DiscoveryRunProgress.step:type_name -> lapp.web.v1.DiscoveryStep - 10, // 17: lapp.web.v1.DiscoveryRunProgress.label_batch:type_name -> lapp.web.v1.DiscoveryLabelBatchProgress - 3, // 18: lapp.web.v1.DiscoveryRunError.step:type_name -> lapp.web.v1.DiscoveryStep - 13, // 19: lapp.web.v1.Pattern.first_seen:type_name -> lapp.web.v1.LineRef - 13, // 20: lapp.web.v1.Pattern.last_seen:type_name -> lapp.web.v1.LineRef - 13, // 21: lapp.web.v1.Pattern.line_refs:type_name -> lapp.web.v1.LineRef - 12, // 22: lapp.web.v1.ErrorPattern.pattern:type_name -> lapp.web.v1.Pattern - 4, // 23: lapp.web.v1.ListWorkspacesResponse.workspaces:type_name -> lapp.web.v1.Workspace - 4, // 24: lapp.web.v1.GetWorkspaceResponse.workspace:type_name -> lapp.web.v1.Workspace - 4, // 25: lapp.web.v1.CreateWorkspaceResponse.workspace:type_name -> lapp.web.v1.Workspace - 5, // 26: lapp.web.v1.ListLogFilesResponse.log_files:type_name -> lapp.web.v1.LogFile - 5, // 27: lapp.web.v1.UploadLogFileResponse.log_file:type_name -> lapp.web.v1.LogFile - 51, // 28: lapp.web.v1.CreateImportRunRequest.from:type_name -> google.protobuf.Timestamp - 51, // 29: lapp.web.v1.CreateImportRunRequest.to:type_name -> google.protobuf.Timestamp - 6, // 30: lapp.web.v1.CreateImportRunResponse.import_run:type_name -> lapp.web.v1.ImportRun - 6, // 31: lapp.web.v1.GetImportRunResponse.import_run:type_name -> lapp.web.v1.ImportRun - 6, // 32: lapp.web.v1.ListImportRunsResponse.import_runs:type_name -> lapp.web.v1.ImportRun - 51, // 33: lapp.web.v1.RecentImportQuery.last_used_at:type_name -> google.protobuf.Timestamp - 37, // 34: lapp.web.v1.ListRecentImportQueriesResponse.recent_queries:type_name -> lapp.web.v1.RecentImportQuery - 8, // 35: lapp.web.v1.CreateDiscoveryRunResponse.discovery_run:type_name -> lapp.web.v1.DiscoveryRun - 8, // 36: lapp.web.v1.GetDiscoveryRunResponse.discovery_run:type_name -> lapp.web.v1.DiscoveryRun - 8, // 37: lapp.web.v1.ListDiscoveryRunsResponse.discovery_runs:type_name -> lapp.web.v1.DiscoveryRun - 12, // 38: lapp.web.v1.ListPatternsResponse.patterns:type_name -> lapp.web.v1.Pattern - 12, // 39: lapp.web.v1.GetPatternResponse.pattern:type_name -> lapp.web.v1.Pattern - 14, // 40: lapp.web.v1.GetErrorsViewResponse.error_patterns:type_name -> lapp.web.v1.ErrorPattern - 15, // 41: lapp.web.v1.GetErrorsViewResponse.unmatched_error_lines:type_name -> lapp.web.v1.UnmatchedErrorLine - 16, // 42: lapp.web.v1.WorkspaceService.ListWorkspaces:input_type -> lapp.web.v1.ListWorkspacesRequest - 18, // 43: lapp.web.v1.WorkspaceService.GetWorkspace:input_type -> lapp.web.v1.GetWorkspaceRequest - 20, // 44: lapp.web.v1.WorkspaceService.CreateWorkspace:input_type -> lapp.web.v1.CreateWorkspaceRequest - 22, // 45: lapp.web.v1.WorkspaceService.DeleteWorkspace:input_type -> lapp.web.v1.DeleteWorkspaceRequest - 24, // 46: lapp.web.v1.WorkspaceService.ListLogFiles:input_type -> lapp.web.v1.ListLogFilesRequest - 26, // 47: lapp.web.v1.WorkspaceService.UploadLogFile:input_type -> lapp.web.v1.UploadLogFileRequest - 28, // 48: lapp.web.v1.WorkspaceService.DeleteLogFile:input_type -> lapp.web.v1.DeleteLogFileRequest - 30, // 49: lapp.web.v1.WorkspaceService.CreateImportRun:input_type -> lapp.web.v1.CreateImportRunRequest - 32, // 50: lapp.web.v1.WorkspaceService.GetImportRun:input_type -> lapp.web.v1.GetImportRunRequest - 34, // 51: lapp.web.v1.WorkspaceService.ListImportRuns:input_type -> lapp.web.v1.ListImportRunsRequest - 36, // 52: lapp.web.v1.WorkspaceService.ListRecentImportQueries:input_type -> lapp.web.v1.ListRecentImportQueriesRequest - 39, // 53: lapp.web.v1.WorkspaceService.CreateDiscoveryRun:input_type -> lapp.web.v1.CreateDiscoveryRunRequest + 8, // 9: lapp.web.v1.ImportRun.error:type_name -> lapp.web.v1.ImportRunError + 6, // 10: lapp.web.v1.ImportRunMetadata.import_run:type_name -> lapp.web.v1.ImportRun + 2, // 11: lapp.web.v1.DiscoveryRun.state:type_name -> lapp.web.v1.DiscoveryRunState + 3, // 12: lapp.web.v1.DiscoveryRun.current_step:type_name -> lapp.web.v1.DiscoveryStep + 51, // 13: lapp.web.v1.DiscoveryRun.started_at:type_name -> google.protobuf.Timestamp + 51, // 14: lapp.web.v1.DiscoveryRun.finished_at:type_name -> google.protobuf.Timestamp + 11, // 15: lapp.web.v1.DiscoveryRun.progress:type_name -> lapp.web.v1.DiscoveryRunProgress + 13, // 16: lapp.web.v1.DiscoveryRun.error:type_name -> lapp.web.v1.DiscoveryRunError + 9, // 17: lapp.web.v1.DiscoveryRunMetadata.discovery_run:type_name -> lapp.web.v1.DiscoveryRun + 3, // 18: lapp.web.v1.DiscoveryRunProgress.step:type_name -> lapp.web.v1.DiscoveryStep + 12, // 19: lapp.web.v1.DiscoveryRunProgress.label_batch:type_name -> lapp.web.v1.DiscoveryLabelBatchProgress + 3, // 20: lapp.web.v1.DiscoveryRunError.step:type_name -> lapp.web.v1.DiscoveryStep + 15, // 21: lapp.web.v1.Pattern.first_seen:type_name -> lapp.web.v1.LineRef + 15, // 22: lapp.web.v1.Pattern.last_seen:type_name -> lapp.web.v1.LineRef + 15, // 23: lapp.web.v1.Pattern.line_refs:type_name -> lapp.web.v1.LineRef + 14, // 24: lapp.web.v1.ErrorPattern.pattern:type_name -> lapp.web.v1.Pattern + 4, // 25: lapp.web.v1.ListWorkspacesResponse.workspaces:type_name -> lapp.web.v1.Workspace + 4, // 26: lapp.web.v1.GetWorkspaceResponse.workspace:type_name -> lapp.web.v1.Workspace + 4, // 27: lapp.web.v1.CreateWorkspaceResponse.workspace:type_name -> lapp.web.v1.Workspace + 5, // 28: lapp.web.v1.ListLogFilesResponse.log_files:type_name -> lapp.web.v1.LogFile + 5, // 29: lapp.web.v1.UploadLogFileResponse.log_file:type_name -> lapp.web.v1.LogFile + 51, // 30: lapp.web.v1.CreateImportRunRequest.from:type_name -> google.protobuf.Timestamp + 51, // 31: lapp.web.v1.CreateImportRunRequest.to:type_name -> google.protobuf.Timestamp + 6, // 32: lapp.web.v1.GetImportRunResponse.import_run:type_name -> lapp.web.v1.ImportRun + 6, // 33: lapp.web.v1.ListImportRunsResponse.import_runs:type_name -> lapp.web.v1.ImportRun + 51, // 34: lapp.web.v1.RecentImportQuery.last_used_at:type_name -> google.protobuf.Timestamp + 38, // 35: lapp.web.v1.ListRecentImportQueriesResponse.recent_queries:type_name -> lapp.web.v1.RecentImportQuery + 9, // 36: lapp.web.v1.GetDiscoveryRunResponse.discovery_run:type_name -> lapp.web.v1.DiscoveryRun + 9, // 37: lapp.web.v1.ListDiscoveryRunsResponse.discovery_runs:type_name -> lapp.web.v1.DiscoveryRun + 14, // 38: lapp.web.v1.ListPatternsResponse.patterns:type_name -> lapp.web.v1.Pattern + 14, // 39: lapp.web.v1.GetPatternResponse.pattern:type_name -> lapp.web.v1.Pattern + 16, // 40: lapp.web.v1.GetErrorsViewResponse.error_patterns:type_name -> lapp.web.v1.ErrorPattern + 17, // 41: lapp.web.v1.GetErrorsViewResponse.unmatched_error_lines:type_name -> lapp.web.v1.UnmatchedErrorLine + 18, // 42: lapp.web.v1.WorkspaceService.ListWorkspaces:input_type -> lapp.web.v1.ListWorkspacesRequest + 20, // 43: lapp.web.v1.WorkspaceService.GetWorkspace:input_type -> lapp.web.v1.GetWorkspaceRequest + 22, // 44: lapp.web.v1.WorkspaceService.CreateWorkspace:input_type -> lapp.web.v1.CreateWorkspaceRequest + 24, // 45: lapp.web.v1.WorkspaceService.DeleteWorkspace:input_type -> lapp.web.v1.DeleteWorkspaceRequest + 26, // 46: lapp.web.v1.WorkspaceService.ListLogFiles:input_type -> lapp.web.v1.ListLogFilesRequest + 28, // 47: lapp.web.v1.WorkspaceService.UploadLogFile:input_type -> lapp.web.v1.UploadLogFileRequest + 30, // 48: lapp.web.v1.WorkspaceService.DeleteLogFile:input_type -> lapp.web.v1.DeleteLogFileRequest + 32, // 49: lapp.web.v1.WorkspaceService.CreateImportRun:input_type -> lapp.web.v1.CreateImportRunRequest + 33, // 50: lapp.web.v1.WorkspaceService.GetImportRun:input_type -> lapp.web.v1.GetImportRunRequest + 35, // 51: lapp.web.v1.WorkspaceService.ListImportRuns:input_type -> lapp.web.v1.ListImportRunsRequest + 37, // 52: lapp.web.v1.WorkspaceService.ListRecentImportQueries:input_type -> lapp.web.v1.ListRecentImportQueriesRequest + 40, // 53: lapp.web.v1.WorkspaceService.CreateDiscoveryRun:input_type -> lapp.web.v1.CreateDiscoveryRunRequest 41, // 54: lapp.web.v1.WorkspaceService.GetDiscoveryRun:input_type -> lapp.web.v1.GetDiscoveryRunRequest 43, // 55: lapp.web.v1.WorkspaceService.ListDiscoveryRuns:input_type -> lapp.web.v1.ListDiscoveryRunsRequest 45, // 56: lapp.web.v1.WorkspaceService.ListPatterns:input_type -> lapp.web.v1.ListPatternsRequest 47, // 57: lapp.web.v1.WorkspaceService.GetPattern:input_type -> lapp.web.v1.GetPatternRequest 49, // 58: lapp.web.v1.WorkspaceService.GetErrorsView:input_type -> lapp.web.v1.GetErrorsViewRequest - 17, // 59: lapp.web.v1.WorkspaceService.ListWorkspaces:output_type -> lapp.web.v1.ListWorkspacesResponse - 19, // 60: lapp.web.v1.WorkspaceService.GetWorkspace:output_type -> lapp.web.v1.GetWorkspaceResponse - 21, // 61: lapp.web.v1.WorkspaceService.CreateWorkspace:output_type -> lapp.web.v1.CreateWorkspaceResponse - 23, // 62: lapp.web.v1.WorkspaceService.DeleteWorkspace:output_type -> lapp.web.v1.DeleteWorkspaceResponse - 25, // 63: lapp.web.v1.WorkspaceService.ListLogFiles:output_type -> lapp.web.v1.ListLogFilesResponse - 27, // 64: lapp.web.v1.WorkspaceService.UploadLogFile:output_type -> lapp.web.v1.UploadLogFileResponse - 29, // 65: lapp.web.v1.WorkspaceService.DeleteLogFile:output_type -> lapp.web.v1.DeleteLogFileResponse - 31, // 66: lapp.web.v1.WorkspaceService.CreateImportRun:output_type -> lapp.web.v1.CreateImportRunResponse - 33, // 67: lapp.web.v1.WorkspaceService.GetImportRun:output_type -> lapp.web.v1.GetImportRunResponse - 35, // 68: lapp.web.v1.WorkspaceService.ListImportRuns:output_type -> lapp.web.v1.ListImportRunsResponse - 38, // 69: lapp.web.v1.WorkspaceService.ListRecentImportQueries:output_type -> lapp.web.v1.ListRecentImportQueriesResponse - 40, // 70: lapp.web.v1.WorkspaceService.CreateDiscoveryRun:output_type -> lapp.web.v1.CreateDiscoveryRunResponse + 19, // 59: lapp.web.v1.WorkspaceService.ListWorkspaces:output_type -> lapp.web.v1.ListWorkspacesResponse + 21, // 60: lapp.web.v1.WorkspaceService.GetWorkspace:output_type -> lapp.web.v1.GetWorkspaceResponse + 23, // 61: lapp.web.v1.WorkspaceService.CreateWorkspace:output_type -> lapp.web.v1.CreateWorkspaceResponse + 25, // 62: lapp.web.v1.WorkspaceService.DeleteWorkspace:output_type -> lapp.web.v1.DeleteWorkspaceResponse + 27, // 63: lapp.web.v1.WorkspaceService.ListLogFiles:output_type -> lapp.web.v1.ListLogFilesResponse + 29, // 64: lapp.web.v1.WorkspaceService.UploadLogFile:output_type -> lapp.web.v1.UploadLogFileResponse + 31, // 65: lapp.web.v1.WorkspaceService.DeleteLogFile:output_type -> lapp.web.v1.DeleteLogFileResponse + 52, // 66: lapp.web.v1.WorkspaceService.CreateImportRun:output_type -> google.longrunning.Operation + 34, // 67: lapp.web.v1.WorkspaceService.GetImportRun:output_type -> lapp.web.v1.GetImportRunResponse + 36, // 68: lapp.web.v1.WorkspaceService.ListImportRuns:output_type -> lapp.web.v1.ListImportRunsResponse + 39, // 69: lapp.web.v1.WorkspaceService.ListRecentImportQueries:output_type -> lapp.web.v1.ListRecentImportQueriesResponse + 52, // 70: lapp.web.v1.WorkspaceService.CreateDiscoveryRun:output_type -> google.longrunning.Operation 42, // 71: lapp.web.v1.WorkspaceService.GetDiscoveryRun:output_type -> lapp.web.v1.GetDiscoveryRunResponse 44, // 72: lapp.web.v1.WorkspaceService.ListDiscoveryRuns:output_type -> lapp.web.v1.ListDiscoveryRunsResponse 46, // 73: lapp.web.v1.WorkspaceService.ListPatterns:output_type -> lapp.web.v1.ListPatternsResponse diff --git a/gen/go/lapp/web/v1/webv1connect/web.connect.go b/gen/go/lapp/web/v1/webv1connect/web.connect.go index 43e7312..b618f37 100644 --- a/gen/go/lapp/web/v1/webv1connect/web.connect.go +++ b/gen/go/lapp/web/v1/webv1connect/web.connect.go @@ -5,6 +5,7 @@ package webv1connect import ( + longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb" connect "connectrpc.com/connect" context "context" errors "errors" @@ -95,11 +96,11 @@ type WorkspaceServiceClient interface { ListLogFiles(context.Context, *connect.Request[v1.ListLogFilesRequest]) (*connect.Response[v1.ListLogFilesResponse], error) UploadLogFile(context.Context, *connect.Request[v1.UploadLogFileRequest]) (*connect.Response[v1.UploadLogFileResponse], error) DeleteLogFile(context.Context, *connect.Request[v1.DeleteLogFileRequest]) (*connect.Response[v1.DeleteLogFileResponse], error) - CreateImportRun(context.Context, *connect.Request[v1.CreateImportRunRequest]) (*connect.Response[v1.CreateImportRunResponse], error) + CreateImportRun(context.Context, *connect.Request[v1.CreateImportRunRequest]) (*connect.Response[longrunningpb.Operation], error) GetImportRun(context.Context, *connect.Request[v1.GetImportRunRequest]) (*connect.Response[v1.GetImportRunResponse], error) ListImportRuns(context.Context, *connect.Request[v1.ListImportRunsRequest]) (*connect.Response[v1.ListImportRunsResponse], error) ListRecentImportQueries(context.Context, *connect.Request[v1.ListRecentImportQueriesRequest]) (*connect.Response[v1.ListRecentImportQueriesResponse], error) - CreateDiscoveryRun(context.Context, *connect.Request[v1.CreateDiscoveryRunRequest]) (*connect.Response[v1.CreateDiscoveryRunResponse], error) + CreateDiscoveryRun(context.Context, *connect.Request[v1.CreateDiscoveryRunRequest]) (*connect.Response[longrunningpb.Operation], error) GetDiscoveryRun(context.Context, *connect.Request[v1.GetDiscoveryRunRequest]) (*connect.Response[v1.GetDiscoveryRunResponse], error) ListDiscoveryRuns(context.Context, *connect.Request[v1.ListDiscoveryRunsRequest]) (*connect.Response[v1.ListDiscoveryRunsResponse], error) ListPatterns(context.Context, *connect.Request[v1.ListPatternsRequest]) (*connect.Response[v1.ListPatternsResponse], error) @@ -160,7 +161,7 @@ func NewWorkspaceServiceClient(httpClient connect.HTTPClient, baseURL string, op connect.WithSchema(workspaceServiceMethods.ByName("DeleteLogFile")), connect.WithClientOptions(opts...), ), - createImportRun: connect.NewClient[v1.CreateImportRunRequest, v1.CreateImportRunResponse]( + createImportRun: connect.NewClient[v1.CreateImportRunRequest, longrunningpb.Operation]( httpClient, baseURL+WorkspaceServiceCreateImportRunProcedure, connect.WithSchema(workspaceServiceMethods.ByName("CreateImportRun")), @@ -184,7 +185,7 @@ func NewWorkspaceServiceClient(httpClient connect.HTTPClient, baseURL string, op connect.WithSchema(workspaceServiceMethods.ByName("ListRecentImportQueries")), connect.WithClientOptions(opts...), ), - createDiscoveryRun: connect.NewClient[v1.CreateDiscoveryRunRequest, v1.CreateDiscoveryRunResponse]( + createDiscoveryRun: connect.NewClient[v1.CreateDiscoveryRunRequest, longrunningpb.Operation]( httpClient, baseURL+WorkspaceServiceCreateDiscoveryRunProcedure, connect.WithSchema(workspaceServiceMethods.ByName("CreateDiscoveryRun")), @@ -232,11 +233,11 @@ type workspaceServiceClient struct { listLogFiles *connect.Client[v1.ListLogFilesRequest, v1.ListLogFilesResponse] uploadLogFile *connect.Client[v1.UploadLogFileRequest, v1.UploadLogFileResponse] deleteLogFile *connect.Client[v1.DeleteLogFileRequest, v1.DeleteLogFileResponse] - createImportRun *connect.Client[v1.CreateImportRunRequest, v1.CreateImportRunResponse] + createImportRun *connect.Client[v1.CreateImportRunRequest, longrunningpb.Operation] getImportRun *connect.Client[v1.GetImportRunRequest, v1.GetImportRunResponse] listImportRuns *connect.Client[v1.ListImportRunsRequest, v1.ListImportRunsResponse] listRecentImportQueries *connect.Client[v1.ListRecentImportQueriesRequest, v1.ListRecentImportQueriesResponse] - createDiscoveryRun *connect.Client[v1.CreateDiscoveryRunRequest, v1.CreateDiscoveryRunResponse] + createDiscoveryRun *connect.Client[v1.CreateDiscoveryRunRequest, longrunningpb.Operation] getDiscoveryRun *connect.Client[v1.GetDiscoveryRunRequest, v1.GetDiscoveryRunResponse] listDiscoveryRuns *connect.Client[v1.ListDiscoveryRunsRequest, v1.ListDiscoveryRunsResponse] listPatterns *connect.Client[v1.ListPatternsRequest, v1.ListPatternsResponse] @@ -280,7 +281,7 @@ func (c *workspaceServiceClient) DeleteLogFile(ctx context.Context, req *connect } // CreateImportRun calls lapp.web.v1.WorkspaceService.CreateImportRun. -func (c *workspaceServiceClient) CreateImportRun(ctx context.Context, req *connect.Request[v1.CreateImportRunRequest]) (*connect.Response[v1.CreateImportRunResponse], error) { +func (c *workspaceServiceClient) CreateImportRun(ctx context.Context, req *connect.Request[v1.CreateImportRunRequest]) (*connect.Response[longrunningpb.Operation], error) { return c.createImportRun.CallUnary(ctx, req) } @@ -300,7 +301,7 @@ func (c *workspaceServiceClient) ListRecentImportQueries(ctx context.Context, re } // CreateDiscoveryRun calls lapp.web.v1.WorkspaceService.CreateDiscoveryRun. -func (c *workspaceServiceClient) CreateDiscoveryRun(ctx context.Context, req *connect.Request[v1.CreateDiscoveryRunRequest]) (*connect.Response[v1.CreateDiscoveryRunResponse], error) { +func (c *workspaceServiceClient) CreateDiscoveryRun(ctx context.Context, req *connect.Request[v1.CreateDiscoveryRunRequest]) (*connect.Response[longrunningpb.Operation], error) { return c.createDiscoveryRun.CallUnary(ctx, req) } @@ -338,11 +339,11 @@ type WorkspaceServiceHandler interface { ListLogFiles(context.Context, *connect.Request[v1.ListLogFilesRequest]) (*connect.Response[v1.ListLogFilesResponse], error) UploadLogFile(context.Context, *connect.Request[v1.UploadLogFileRequest]) (*connect.Response[v1.UploadLogFileResponse], error) DeleteLogFile(context.Context, *connect.Request[v1.DeleteLogFileRequest]) (*connect.Response[v1.DeleteLogFileResponse], error) - CreateImportRun(context.Context, *connect.Request[v1.CreateImportRunRequest]) (*connect.Response[v1.CreateImportRunResponse], error) + CreateImportRun(context.Context, *connect.Request[v1.CreateImportRunRequest]) (*connect.Response[longrunningpb.Operation], error) GetImportRun(context.Context, *connect.Request[v1.GetImportRunRequest]) (*connect.Response[v1.GetImportRunResponse], error) ListImportRuns(context.Context, *connect.Request[v1.ListImportRunsRequest]) (*connect.Response[v1.ListImportRunsResponse], error) ListRecentImportQueries(context.Context, *connect.Request[v1.ListRecentImportQueriesRequest]) (*connect.Response[v1.ListRecentImportQueriesResponse], error) - CreateDiscoveryRun(context.Context, *connect.Request[v1.CreateDiscoveryRunRequest]) (*connect.Response[v1.CreateDiscoveryRunResponse], error) + CreateDiscoveryRun(context.Context, *connect.Request[v1.CreateDiscoveryRunRequest]) (*connect.Response[longrunningpb.Operation], error) GetDiscoveryRun(context.Context, *connect.Request[v1.GetDiscoveryRunRequest]) (*connect.Response[v1.GetDiscoveryRunResponse], error) ListDiscoveryRuns(context.Context, *connect.Request[v1.ListDiscoveryRunsRequest]) (*connect.Response[v1.ListDiscoveryRunsResponse], error) ListPatterns(context.Context, *connect.Request[v1.ListPatternsRequest]) (*connect.Response[v1.ListPatternsResponse], error) @@ -532,7 +533,7 @@ func (UnimplementedWorkspaceServiceHandler) DeleteLogFile(context.Context, *conn return nil, connect.NewError(connect.CodeUnimplemented, errors.New("lapp.web.v1.WorkspaceService.DeleteLogFile is not implemented")) } -func (UnimplementedWorkspaceServiceHandler) CreateImportRun(context.Context, *connect.Request[v1.CreateImportRunRequest]) (*connect.Response[v1.CreateImportRunResponse], error) { +func (UnimplementedWorkspaceServiceHandler) CreateImportRun(context.Context, *connect.Request[v1.CreateImportRunRequest]) (*connect.Response[longrunningpb.Operation], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("lapp.web.v1.WorkspaceService.CreateImportRun is not implemented")) } @@ -548,7 +549,7 @@ func (UnimplementedWorkspaceServiceHandler) ListRecentImportQueries(context.Cont return nil, connect.NewError(connect.CodeUnimplemented, errors.New("lapp.web.v1.WorkspaceService.ListRecentImportQueries is not implemented")) } -func (UnimplementedWorkspaceServiceHandler) CreateDiscoveryRun(context.Context, *connect.Request[v1.CreateDiscoveryRunRequest]) (*connect.Response[v1.CreateDiscoveryRunResponse], error) { +func (UnimplementedWorkspaceServiceHandler) CreateDiscoveryRun(context.Context, *connect.Request[v1.CreateDiscoveryRunRequest]) (*connect.Response[longrunningpb.Operation], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("lapp.web.v1.WorkspaceService.CreateDiscoveryRun is not implemented")) } diff --git a/go.mod b/go.mod index 32c6055..b097338 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.25.7 require ( cloud.google.com/go/logging v1.19.0 + cloud.google.com/go/longrunning v1.2.0 connectrpc.com/connect v1.20.0 github.com/bytedance/sonic v1.15.0 github.com/cloudwego/eino v0.8.0 @@ -21,6 +22,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0 go.opentelemetry.io/otel/sdk v1.44.0 google.golang.org/api v0.290.0 + google.golang.org/genproto/googleapis/rpc v0.0.0-20260706201446-f0a921348800 google.golang.org/protobuf v1.36.11 ) @@ -30,7 +32,6 @@ require ( cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.9.0 // indirect cloud.google.com/go/iam v1.11.0 // indirect - cloud.google.com/go/longrunning v1.2.0 // indirect github.com/apache/arrow-go/v18 v18.5.1 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/buger/jsonparser v1.1.1 // indirect @@ -108,7 +109,6 @@ require ( golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260630182238-925bb5da69e7 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260706201446-f0a921348800 // indirect google.golang.org/grpc v1.82.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/webapp/import_service.go b/pkg/webapp/import_service.go index 8e4ea09..ddf35e9 100644 --- a/pkg/webapp/import_service.go +++ b/pkg/webapp/import_service.go @@ -10,6 +10,7 @@ import ( "strings" "time" + longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb" "connectrpc.com/connect" "github.com/go-errors/errors" "github.com/google/uuid" @@ -21,7 +22,7 @@ import ( const defaultImportLimit = 100000 const recentImportQueryLimit = 20 -func (s *WorkspaceService) CreateImportRun(_ context.Context, req *connect.Request[webv1.CreateImportRunRequest]) (*connect.Response[webv1.CreateImportRunResponse], error) { +func (s *WorkspaceService) CreateImportRun(_ context.Context, req *connect.Request[webv1.CreateImportRunRequest]) (*connect.Response[longrunningpb.Operation], error) { id, connectErr := workspaceIDFromName(req.Msg.Parent) if connectErr != nil { return nil, connectErr @@ -38,7 +39,7 @@ func (s *WorkspaceService) CreateImportRun(_ context.Context, req *connect.Reque } if !s.reserveRun(id) { - return nil, connect.NewError(connect.CodeFailedPrecondition, errors.New("another run is active")) + return nil, connect.NewError(connect.CodeAborted, errors.New("another run is active")) } if connectErr := s.ensureWorkspaceExists(id); connectErr != nil { s.releaseRun(id) @@ -64,7 +65,7 @@ func (s *WorkspaceService) CreateImportRun(_ context.Context, req *connect.Reque s.releaseRun(id) return nil, connect.NewError(connect.CodeInternal, err) } - message, err := s.importRunMessage(id, record) + operation, err := s.importRunOperation(id, record) if err != nil { s.releaseRun(id) return nil, connect.NewError(connect.CodeInternal, err) @@ -89,9 +90,7 @@ func (s *WorkspaceService) CreateImportRun(_ context.Context, req *connect.Reque } }() - return connect.NewResponse(&webv1.CreateImportRunResponse{ - ImportRun: message, - }), nil + return connect.NewResponse(operation), nil } func validateImportRunRequest(req *webv1.CreateImportRunRequest) (from, to time.Time, limit int, connectErr *connect.Error) { diff --git a/pkg/webapp/import_service_test.go b/pkg/webapp/import_service_test.go index d7fb7b9..13dd2ef 100644 --- a/pkg/webapp/import_service_test.go +++ b/pkg/webapp/import_service_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb" "connectrpc.com/connect" webv1 "github.com/strrl/lapp/gen/go/lapp/web/v1" "github.com/strrl/lapp/pkg/semantic" @@ -147,12 +148,20 @@ func TestWorkspaceServiceImportRunAsyncSuccess(t *testing.T) { if err != nil { t.Fatalf("CreateImportRun: %v", err) } - runName := response.Msg.ImportRun.Name + startedRun := importRunFromOperation(t, response.Msg) + runName := startedRun.Name + operationName := response.Msg.Name if runName == "" { t.Fatal("CreateImportRun returned an empty run name") } - if response.Msg.ImportRun.Limit != defaultImportLimit { - t.Fatalf("run limit = %d, want %d", response.Msg.ImportRun.Limit, defaultImportLimit) + if operationName != workspaceName+"/operations/"+startedRun.ImportRunId { + t.Fatalf("operation name = %q", operationName) + } + if response.Msg.Done { + t.Fatal("new import operation is already done") + } + if startedRun.Limit != defaultImportLimit { + t.Fatalf("run limit = %d, want %d", startedRun.Limit, defaultImportLimit) } immediate, err := service.GetImportRun(context.Background(), connect.NewRequest(&webv1.GetImportRunRequest{Name: runName})) @@ -187,6 +196,20 @@ func TestWorkspaceServiceImportRunAsyncSuccess(t *testing.T) { if string(content) != line+"\n" { t.Fatalf("imported log content = %q", content) } + completed, err := service.GetOperation(context.Background(), connect.NewRequest(&longrunningpb.GetOperationRequest{Name: operationName})) + if err != nil { + t.Fatalf("GetOperation: %v", err) + } + if !completed.Msg.Done || completed.Msg.GetResponse() == nil { + t.Fatalf("completed import operation = %+v", completed.Msg) + } + var result webv1.ImportRun + if err := completed.Msg.GetResponse().UnmarshalTo(&result); err != nil { + t.Fatalf("unmarshal import response: %v", err) + } + if result.Name != runName { + t.Fatalf("operation response run = %q, want %q", result.Name, runName) + } } func TestWorkspaceServiceImportRunFailure(t *testing.T) { @@ -198,13 +221,20 @@ func TestWorkspaceServiceImportRunFailure(t *testing.T) { if err != nil { t.Fatalf("CreateImportRun: %v", err) } - run := waitForImportRunState(t, service, response.Msg.ImportRun.Name, webv1.ImportRunState_IMPORT_RUN_STATE_FAILED) + run := waitForImportRunState(t, service, importRunFromOperation(t, response.Msg).Name, webv1.ImportRunState_IMPORT_RUN_STATE_FAILED) if run.Error == nil || run.Error.Code != "FETCH_FAILED" { t.Fatalf("unexpected import error: %+v", run.Error) } if run.FinishedAt == nil { t.Fatal("failed run has no finished_at") } + failed, err := service.GetOperation(context.Background(), connect.NewRequest(&longrunningpb.GetOperationRequest{Name: response.Msg.Name})) + if err != nil { + t.Fatalf("GetOperation: %v", err) + } + if !failed.Msg.Done || failed.Msg.GetError().Code != int32(connect.CodeInternal) { + t.Fatalf("failed import operation = %+v", failed.Msg) + } } func TestWorkspaceServiceImportRunTruncation(t *testing.T) { @@ -219,7 +249,7 @@ func TestWorkspaceServiceImportRunTruncation(t *testing.T) { if err != nil { t.Fatalf("CreateImportRun: %v", err) } - run := waitForImportRunState(t, service, response.Msg.ImportRun.Name, webv1.ImportRunState_IMPORT_RUN_STATE_SUCCEEDED) + run := waitForImportRunState(t, service, importRunFromOperation(t, response.Msg).Name, webv1.ImportRunState_IMPORT_RUN_STATE_SUCCEEDED) if !run.Truncated { t.Fatalf("expected truncated run: %+v", run) } @@ -299,10 +329,12 @@ func TestWorkspaceServiceRunMutualExclusion(t *testing.T) { failedPreconditions := []struct { name string + code connect.Code call func() error }{ { name: "second import", + code: connect.CodeAborted, call: func() error { _, err := service.CreateImportRun(context.Background(), connect.NewRequest(validImportRequest(importWorkspace))) return err @@ -310,6 +342,7 @@ func TestWorkspaceServiceRunMutualExclusion(t *testing.T) { }, { name: "discovery", + code: connect.CodeAborted, call: func() error { _, err := service.CreateDiscoveryRun(context.Background(), connect.NewRequest(&webv1.CreateDiscoveryRunRequest{Parent: importWorkspace})) return err @@ -317,6 +350,7 @@ func TestWorkspaceServiceRunMutualExclusion(t *testing.T) { }, { name: "upload", + code: connect.CodeFailedPrecondition, call: func() error { _, err := service.UploadLogFile(context.Background(), connect.NewRequest(&webv1.UploadLogFileRequest{ Parent: importWorkspace, @@ -328,6 +362,7 @@ func TestWorkspaceServiceRunMutualExclusion(t *testing.T) { }, { name: "delete log", + code: connect.CodeFailedPrecondition, call: func() error { _, err := service.DeleteLogFile(context.Background(), connect.NewRequest(&webv1.DeleteLogFileRequest{ Name: importWorkspace + "/logFiles/app.log", @@ -337,6 +372,7 @@ func TestWorkspaceServiceRunMutualExclusion(t *testing.T) { }, { name: "delete workspace", + code: connect.CodeFailedPrecondition, call: func() error { _, err := service.DeleteWorkspace(context.Background(), connect.NewRequest(&webv1.DeleteWorkspaceRequest{Name: importWorkspace})) return err @@ -345,14 +381,14 @@ func TestWorkspaceServiceRunMutualExclusion(t *testing.T) { } for _, test := range failedPreconditions { t.Run("import blocks "+test.name, func(t *testing.T) { - if err := test.call(); connect.CodeOf(err) != connect.CodeFailedPrecondition { - t.Fatalf("code = %s, want failed_precondition: %v", connect.CodeOf(err), err) + if err := test.call(); connect.CodeOf(err) != test.code { + t.Fatalf("code = %s, want %s: %v", connect.CodeOf(err), test.code, err) } }) } close(releaseImport) - waitForImportRunState(t, service, importResponse.Msg.ImportRun.Name, webv1.ImportRunState_IMPORT_RUN_STATE_SUCCEEDED) + waitForImportRunState(t, service, importRunFromOperation(t, importResponse.Msg).Name, webv1.ImportRunState_IMPORT_RUN_STATE_SUCCEEDED) discoveryResponse, err := service.CreateDiscoveryRun(context.Background(), connect.NewRequest(&webv1.CreateDiscoveryRunRequest{ Parent: discoveryWorkspace, @@ -365,11 +401,11 @@ func TestWorkspaceServiceRunMutualExclusion(t *testing.T) { case <-time.After(2 * time.Second): t.Fatal("discovery labeler did not start") } - if _, err := service.CreateImportRun(context.Background(), connect.NewRequest(validImportRequest(discoveryWorkspace))); connect.CodeOf(err) != connect.CodeFailedPrecondition { - t.Fatalf("CreateImportRun during discovery code = %s, want failed_precondition: %v", connect.CodeOf(err), err) + if _, err := service.CreateImportRun(context.Background(), connect.NewRequest(validImportRequest(discoveryWorkspace))); connect.CodeOf(err) != connect.CodeAborted { + t.Fatalf("CreateImportRun during discovery code = %s, want aborted: %v", connect.CodeOf(err), err) } close(releaseDiscovery) - waitForRunState(t, service, discoveryResponse.Msg.DiscoveryRun.Name, webv1.DiscoveryRunState_DISCOVERY_RUN_STATE_SUCCEEDED) + waitForRunState(t, service, discoveryRunFromOperation(t, discoveryResponse.Msg).Name, webv1.DiscoveryRunState_DISCOVERY_RUN_STATE_SUCCEEDED) } func TestNewWorkspaceServiceMarksInterruptedImportRunsFailed(t *testing.T) { @@ -381,7 +417,8 @@ func TestNewWorkspaceServiceMarksInterruptedImportRunsFailed(t *testing.T) { writeImportRecord(t, workspaceDir, "running", "acme-prod", "severity>=ERROR", startedAt, workspace.ImportRunStateRunning) writeImportRecord(t, workspaceDir, "succeeded", "acme-prod", "severity>=ERROR", startedAt, workspace.ImportRunStateSucceeded) - if _, err := NewWorkspaceService(ServiceConfig{Root: root}); err != nil { + service, err := NewWorkspaceService(ServiceConfig{Root: root}) + if err != nil { t.Fatalf("NewWorkspaceService: %v", err) } for _, id := range []string{"queued", "running"} { @@ -395,6 +432,15 @@ func TestNewWorkspaceServiceMarksInterruptedImportRunsFailed(t *testing.T) { if record.Error == nil || record.Error.Code != "IMPORT_INTERRUPTED" { t.Fatalf("unexpected interrupted error for %s: %+v", id, record.Error) } + operation, err := service.GetOperation(context.Background(), connect.NewRequest(&longrunningpb.GetOperationRequest{ + Name: "workspaces/imports/operations/" + id, + })) + if err != nil { + t.Fatalf("GetOperation %s: %v", id, err) + } + if !operation.Msg.Done || operation.Msg.GetError().Code != int32(connect.CodeAborted) { + t.Fatalf("interrupted operation %s = %+v", id, operation.Msg) + } } record, err := workspace.ReadImportRunRecord(workspaceDir, "succeeded") if err != nil { diff --git a/pkg/webapp/operations_service.go b/pkg/webapp/operations_service.go new file mode 100644 index 0000000..e2e998c --- /dev/null +++ b/pkg/webapp/operations_service.go @@ -0,0 +1,171 @@ +package webapp + +import ( + "context" + "os" + "strings" + + longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb" + "connectrpc.com/connect" + "github.com/go-errors/errors" + longrunningpbconnect "github.com/strrl/lapp/gen/go/google/longrunning/longrunningpbconnect" + webv1 "github.com/strrl/lapp/gen/go/lapp/web/v1" + "github.com/strrl/lapp/pkg/workspace" + statuspb "google.golang.org/genproto/googleapis/rpc/status" + "google.golang.org/protobuf/types/known/anypb" + "google.golang.org/protobuf/types/known/emptypb" +) + +var _ longrunningpbconnect.OperationsHandler = (*WorkspaceService)(nil) + +func (s *WorkspaceService) ListOperations(context.Context, *connect.Request[longrunningpb.ListOperationsRequest]) (*connect.Response[longrunningpb.ListOperationsResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("listing operations is not supported")) +} + +func (s *WorkspaceService) GetOperation(_ context.Context, req *connect.Request[longrunningpb.GetOperationRequest]) (*connect.Response[longrunningpb.Operation], error) { + operation, connectErr := s.operationByName(req.Msg.Name) + if connectErr != nil { + return nil, connectErr + } + return connect.NewResponse(operation), nil +} + +func (s *WorkspaceService) DeleteOperation(context.Context, *connect.Request[longrunningpb.DeleteOperationRequest]) (*connect.Response[emptypb.Empty], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("deleting operations is not supported")) +} + +func (s *WorkspaceService) CancelOperation(context.Context, *connect.Request[longrunningpb.CancelOperationRequest]) (*connect.Response[emptypb.Empty], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("cancelling operations is not supported")) +} + +func (s *WorkspaceService) WaitOperation(_ context.Context, req *connect.Request[longrunningpb.WaitOperationRequest]) (*connect.Response[longrunningpb.Operation], error) { + operation, connectErr := s.operationByName(req.Msg.Name) + if connectErr != nil { + return nil, connectErr + } + return connect.NewResponse(operation), nil +} + +func (s *WorkspaceService) operationByName(name string) (*longrunningpb.Operation, *connect.Error) { + workspaceID, runID, connectErr := operationNameFromResource(name) + if connectErr != nil { + return nil, connectErr + } + + importRecord, err := workspace.ReadImportRunRecord(s.workspaceDir(workspaceID), runID) + if err == nil { + operation, err := s.importRunOperation(workspaceID, importRecord) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + return operation, nil + } + if !errors.Is(err, os.ErrNotExist) { + return nil, connect.NewError(connect.CodeInternal, err) + } + + discoveryRecord, err := workspace.ReadDiscoveryRunRecord(s.workspaceDir(workspaceID), runID) + if err == nil { + operation, err := s.discoveryRunOperation(workspaceID, discoveryRecord) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + return operation, nil + } + if !errors.Is(err, os.ErrNotExist) { + return nil, connect.NewError(connect.CodeInternal, err) + } + return nil, connect.NewError(connect.CodeNotFound, errors.Errorf("operation %q not found", name)) +} + +func (s *WorkspaceService) importRunOperation(workspaceID string, record workspace.ImportRunRecord) (*longrunningpb.Operation, error) { + run, err := s.importRunMessage(workspaceID, record) + if err != nil { + return nil, err + } + metadata, err := anypb.New(&webv1.ImportRunMetadata{ImportRun: run}) + if err != nil { + return nil, err + } + operation := &longrunningpb.Operation{ + Name: operationName(workspaceID, record.ID), + Metadata: metadata, + } + switch record.State { + case workspace.ImportRunStateQueued, workspace.ImportRunStateRunning: + return operation, nil + case workspace.ImportRunStateSucceeded: + response, err := anypb.New(run) + if err != nil { + return nil, err + } + operation.Done = true + operation.Result = &longrunningpb.Operation_Response{Response: response} + case workspace.ImportRunStateFailed: + code := "IMPORT_FAILED" + message := "Import failed" + if record.Error != nil { + code = record.Error.Code + message = record.Error.Message + } + operation.Done = true + operation.Result = &longrunningpb.Operation_Error{Error: operationError(code, message)} + } + return operation, nil +} + +func (s *WorkspaceService) discoveryRunOperation(workspaceID string, record workspace.DiscoveryRunRecord) (*longrunningpb.Operation, error) { + run := s.discoveryRunMessage(workspaceID, record) + metadata, err := anypb.New(&webv1.DiscoveryRunMetadata{DiscoveryRun: run}) + if err != nil { + return nil, err + } + operation := &longrunningpb.Operation{ + Name: operationName(workspaceID, record.ID), + Metadata: metadata, + } + switch record.State { + case workspace.DiscoveryRunStateQueued, workspace.DiscoveryRunStateRunning: + return operation, nil + case workspace.DiscoveryRunStateSucceeded: + response, err := anypb.New(run) + if err != nil { + return nil, err + } + operation.Done = true + operation.Result = &longrunningpb.Operation_Response{Response: response} + case workspace.DiscoveryRunStateFailed: + code := "DISCOVERY_FAILED" + message := "Discovery failed" + if record.Error != nil { + code = record.Error.Code + message = record.Error.Message + } + operation.Done = true + operation.Result = &longrunningpb.Operation_Error{Error: operationError(code, message)} + } + return operation, nil +} + +func operationError(errorCode, message string) *statuspb.Status { + code := connect.CodeInternal + if strings.HasSuffix(errorCode, "_INTERRUPTED") { + code = connect.CodeAborted + } + return &statuspb.Status{ + Code: int32(code), + Message: message, + } +} + +func operationName(workspaceID, runID string) string { + return workspaceName(workspaceID) + "/operations/" + runID +} + +func operationNameFromResource(name string) (workspaceID, runID string, err *connect.Error) { + parts := strings.Split(strings.Trim(name, "/"), "/") + if len(parts) == 4 && parts[0] == "workspaces" && parts[2] == "operations" && validResourcePart(parts[1]) && validResourcePart(parts[3]) { + return parts[1], parts[3], nil + } + return "", "", connect.NewError(connect.CodeInvalidArgument, errors.Errorf("invalid operation name %q", name)) +} diff --git a/pkg/webapp/server.go b/pkg/webapp/server.go index 7408411..7b907f6 100644 --- a/pkg/webapp/server.go +++ b/pkg/webapp/server.go @@ -11,6 +11,7 @@ import ( "strings" "github.com/go-errors/errors" + longrunningpbconnect "github.com/strrl/lapp/gen/go/google/longrunning/longrunningpbconnect" "github.com/strrl/lapp/gen/go/lapp/web/v1/webv1connect" "github.com/strrl/lapp/pkg/gcplog" "github.com/strrl/lapp/pkg/workspace" @@ -58,6 +59,8 @@ func NewHandler(config ServerConfig) (http.Handler, error) { mux := http.NewServeMux() path, handler := webv1connect.NewWorkspaceServiceHandler(service) mux.Handle(path, otelhttp.NewHandler(handler, "connect.WorkspaceService")) + path, handler = longrunningpbconnect.NewOperationsHandler(service) + mux.Handle(path, otelhttp.NewHandler(handler, "connect.Operations")) staticHandler, err := staticFileHandler(config.StaticDir) if err != nil { return nil, err diff --git a/pkg/webapp/service.go b/pkg/webapp/service.go index fea60fc..0f0aee2 100644 --- a/pkg/webapp/service.go +++ b/pkg/webapp/service.go @@ -12,6 +12,7 @@ import ( "sync" "time" + longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb" "connectrpc.com/connect" "github.com/go-errors/errors" "github.com/google/uuid" @@ -216,7 +217,7 @@ func (s *WorkspaceService) DeleteLogFile(_ context.Context, req *connect.Request return connect.NewResponse(&webv1.DeleteLogFileResponse{}), nil } -func (s *WorkspaceService) CreateDiscoveryRun(_ context.Context, req *connect.Request[webv1.CreateDiscoveryRunRequest]) (*connect.Response[webv1.CreateDiscoveryRunResponse], error) { +func (s *WorkspaceService) CreateDiscoveryRun(_ context.Context, req *connect.Request[webv1.CreateDiscoveryRunRequest]) (*connect.Response[longrunningpb.Operation], error) { id, connectErr := workspaceIDFromName(req.Msg.Parent) if connectErr != nil { return nil, connectErr @@ -225,7 +226,7 @@ func (s *WorkspaceService) CreateDiscoveryRun(_ context.Context, req *connect.Re return nil, connectErr } if !s.reserveRun(id) { - return nil, connect.NewError(connect.CodeFailedPrecondition, errors.New("another run is active")) + return nil, connect.NewError(connect.CodeAborted, errors.New("another run is active")) } if connectErr := s.ensureWorkspaceExists(id); connectErr != nil { s.releaseRun(id) @@ -258,6 +259,11 @@ func (s *WorkspaceService) CreateDiscoveryRun(_ context.Context, req *connect.Re s.releaseRun(id) return nil, connect.NewError(connect.CodeInternal, err) } + operation, err := s.discoveryRunOperation(id, record) + if err != nil { + s.releaseRun(id) + return nil, connect.NewError(connect.CodeInternal, err) + } go func() { defer s.releaseRun(id) slog.Info("DiscoveryRun started", "workspace", id, "run", runID.String()) @@ -282,7 +288,7 @@ func (s *WorkspaceService) CreateDiscoveryRun(_ context.Context, req *connect.Re "unmatched", result.UnmatchedCount, ) }() - return connect.NewResponse(&webv1.CreateDiscoveryRunResponse{DiscoveryRun: s.discoveryRunMessage(id, record)}), nil + return connect.NewResponse(operation), nil } func (s *WorkspaceService) GetDiscoveryRun(_ context.Context, req *connect.Request[webv1.GetDiscoveryRunRequest]) (*connect.Response[webv1.GetDiscoveryRunResponse], error) { diff --git a/pkg/webapp/service_test.go b/pkg/webapp/service_test.go index df57187..ad9c5a4 100644 --- a/pkg/webapp/service_test.go +++ b/pkg/webapp/service_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + longrunningpb "cloud.google.com/go/longrunning/autogen/longrunningpb" "connectrpc.com/connect" webv1 "github.com/strrl/lapp/gen/go/lapp/web/v1" "github.com/strrl/lapp/pkg/semantic" @@ -65,9 +66,16 @@ func TestWorkspaceServiceDiscoveryFlow(t *testing.T) { if err != nil { t.Fatalf("CreateDiscoveryRun: %v", err) } - runName := runResponse.Msg.DiscoveryRun.Name - if runResponse.Msg.DiscoveryRun.State != webv1.DiscoveryRunState_DISCOVERY_RUN_STATE_RUNNING { - t.Fatalf("expected running run, got %s", runResponse.Msg.DiscoveryRun.State) + startedRun := discoveryRunFromOperation(t, runResponse.Msg) + runName := startedRun.Name + if runResponse.Msg.Name != workspaceName+"/operations/"+startedRun.DiscoveryRunId { + t.Fatalf("operation name = %q", runResponse.Msg.Name) + } + if runResponse.Msg.Done { + t.Fatal("new discovery operation is already done") + } + if startedRun.State != webv1.DiscoveryRunState_DISCOVERY_RUN_STATE_RUNNING { + t.Fatalf("expected running run, got %s", startedRun.State) } if _, err := service.DeleteLogFile(context.Background(), connect.NewRequest(&webv1.DeleteLogFileRequest{ Name: workspaceName + "/logFiles/app.log", @@ -76,12 +84,26 @@ func TestWorkspaceServiceDiscoveryFlow(t *testing.T) { } if _, err := service.CreateDiscoveryRun(context.Background(), connect.NewRequest(&webv1.CreateDiscoveryRunRequest{ Parent: workspaceName, - })); connect.CodeOf(err) != connect.CodeFailedPrecondition { + })); connect.CodeOf(err) != connect.CodeAborted { t.Fatalf("expected concurrent discovery to be rejected, got %v", err) } close(done) waitForRunState(t, service, runName, webv1.DiscoveryRunState_DISCOVERY_RUN_STATE_SUCCEEDED) + completed, err := service.GetOperation(context.Background(), connect.NewRequest(&longrunningpb.GetOperationRequest{Name: runResponse.Msg.Name})) + if err != nil { + t.Fatalf("GetOperation: %v", err) + } + if !completed.Msg.Done || completed.Msg.GetResponse() == nil { + t.Fatalf("completed discovery operation = %+v", completed.Msg) + } + var discovered webv1.DiscoveryRun + if err := completed.Msg.GetResponse().UnmarshalTo(&discovered); err != nil { + t.Fatalf("unmarshal discovery response: %v", err) + } + if discovered.Name != runName { + t.Fatalf("operation response run = %q, want %q", discovered.Name, runName) + } patterns, err := service.ListPatterns(context.Background(), connect.NewRequest(&webv1.ListPatternsRequest{ Parent: runName, @@ -188,7 +210,7 @@ func TestWorkspaceServiceDiscoveryFailureRecordsErrorMessage(t *testing.T) { if err != nil { t.Fatalf("CreateDiscoveryRun: %v", err) } - run := waitForRunState(t, service, runResponse.Msg.DiscoveryRun.Name, webv1.DiscoveryRunState_DISCOVERY_RUN_STATE_FAILED) + run := waitForRunState(t, service, discoveryRunFromOperation(t, runResponse.Msg).Name, webv1.DiscoveryRunState_DISCOVERY_RUN_STATE_FAILED) if run.Error == nil || !strings.Contains(run.Error.Message, "semantic labeling unavailable") { t.Fatalf("expected failed run to expose semantic error, got %+v", run) } @@ -283,3 +305,33 @@ func waitForRunState(t *testing.T, service *WorkspaceService, runName string, st t.Fatalf("discovery run did not reach %s", state) return nil } + +func discoveryRunFromOperation(t *testing.T, operation *longrunningpb.Operation) *webv1.DiscoveryRun { + t.Helper() + var metadata webv1.DiscoveryRunMetadata + if operation.Metadata == nil { + t.Fatal("operation has no discovery metadata") + } + if err := operation.Metadata.UnmarshalTo(&metadata); err != nil { + t.Fatalf("unmarshal discovery metadata: %v", err) + } + if metadata.DiscoveryRun == nil { + t.Fatal("operation metadata has no discovery run") + } + return metadata.DiscoveryRun +} + +func importRunFromOperation(t *testing.T, operation *longrunningpb.Operation) *webv1.ImportRun { + t.Helper() + var metadata webv1.ImportRunMetadata + if operation.Metadata == nil { + t.Fatal("operation has no import metadata") + } + if err := operation.Metadata.UnmarshalTo(&metadata); err != nil { + t.Fatalf("unmarshal import metadata: %v", err) + } + if metadata.ImportRun == nil { + t.Fatal("operation metadata has no import run") + } + return metadata.ImportRun +} diff --git a/proto/lapp/web/v1/web.proto b/proto/lapp/web/v1/web.proto index 140e553..eabf772 100644 --- a/proto/lapp/web/v1/web.proto +++ b/proto/lapp/web/v1/web.proto @@ -4,6 +4,7 @@ package lapp.web.v1; option go_package = "github.com/strrl/lapp/gen/go/lapp/web/v1;webv1"; +import "google/longrunning/operations.proto"; import "google/protobuf/timestamp.proto"; service WorkspaceService { @@ -16,12 +17,22 @@ service WorkspaceService { rpc UploadLogFile(UploadLogFileRequest) returns (UploadLogFileResponse); rpc DeleteLogFile(DeleteLogFileRequest) returns (DeleteLogFileResponse); - rpc CreateImportRun(CreateImportRunRequest) returns (CreateImportRunResponse); + rpc CreateImportRun(CreateImportRunRequest) returns (google.longrunning.Operation) { + option (google.longrunning.operation_info) = { + response_type: "ImportRun" + metadata_type: "ImportRunMetadata" + }; + } rpc GetImportRun(GetImportRunRequest) returns (GetImportRunResponse); rpc ListImportRuns(ListImportRunsRequest) returns (ListImportRunsResponse); rpc ListRecentImportQueries(ListRecentImportQueriesRequest) returns (ListRecentImportQueriesResponse); - rpc CreateDiscoveryRun(CreateDiscoveryRunRequest) returns (CreateDiscoveryRunResponse); + rpc CreateDiscoveryRun(CreateDiscoveryRunRequest) returns (google.longrunning.Operation) { + option (google.longrunning.operation_info) = { + response_type: "DiscoveryRun" + metadata_type: "DiscoveryRunMetadata" + }; + } rpc GetDiscoveryRun(GetDiscoveryRunRequest) returns (GetDiscoveryRunResponse); rpc ListDiscoveryRuns(ListDiscoveryRunsRequest) returns (ListDiscoveryRunsResponse); @@ -73,6 +84,10 @@ message ImportRun { ImportRunError error = 15; } +message ImportRunMetadata { + ImportRun import_run = 1; +} + message ImportRunError { string code = 1; string message = 2; @@ -102,6 +117,10 @@ message DiscoveryRun { DiscoveryRunError error = 13; } +message DiscoveryRunMetadata { + DiscoveryRun discovery_run = 1; +} + message DiscoveryRunProgress { DiscoveryStep step = 1; DiscoveryLabelBatchProgress label_batch = 2; @@ -229,10 +248,6 @@ message CreateImportRunRequest { int32 limit = 6; } -message CreateImportRunResponse { - ImportRun import_run = 1; -} - message GetImportRunRequest { string name = 1; } @@ -266,10 +281,6 @@ message CreateDiscoveryRunRequest { string model = 2; } -message CreateDiscoveryRunResponse { - DiscoveryRun discovery_run = 1; -} - message GetDiscoveryRunRequest { string name = 1; } From 2f4d846caca2d1022415a94f780773dde03fcbed Mon Sep 17 00:00:00 2001 From: Zhiqiang ZHOU Date: Sun, 26 Jul 2026 12:18:55 -0700 Subject: [PATCH 2/2] mark generated code --- .gitattributes | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..3333dba --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +/frontend/src/gen/** linguist-generated=true +/gen/go/** linguist-generated=true