diff --git a/.gitignore b/.gitignore index 7624e00c..7c2576f2 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ deps/* .idea .vscode +coverage diff --git a/jest.config.js b/jest.config.js index a6110529..e3471a95 100644 --- a/jest.config.js +++ b/jest.config.js @@ -3,4 +3,3 @@ module.exports = { '^.+\\.tsx?$': 'ts-jest', }, }; - \ No newline at end of file diff --git a/proto/test/schemaregistry/serde/cycle.proto b/proto/test/schemaregistry/serde/cycle.proto new file mode 100644 index 00000000..a5351102 --- /dev/null +++ b/proto/test/schemaregistry/serde/cycle.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +package test; +option go_package="../test"; + +message LinkedList { + int32 value = 1; + LinkedList next = 10; +} \ No newline at end of file diff --git a/proto/test/schemaregistry/serde/dep.proto b/proto/test/schemaregistry/serde/dep.proto new file mode 100644 index 00000000..c0beccf9 --- /dev/null +++ b/proto/test/schemaregistry/serde/dep.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +package test; +option go_package="../test"; + +import "test/schemaregistry/serde/test.proto"; + +message DependencyMessage { + bool is_active = 1; + TestMessage test_messsage = 2; +} diff --git a/proto/test/schemaregistry/serde/example.proto b/proto/test/schemaregistry/serde/example.proto new file mode 100644 index 00000000..a8e65fca --- /dev/null +++ b/proto/test/schemaregistry/serde/example.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + +package test; +option go_package="../test"; + +import "confluent/meta.proto"; + +message Author { + string name = 1 [ + (confluent.field_meta).tags = "PII" + ]; + int32 id = 2; + bytes picture = 3 [ + (confluent.field_meta).tags = "PII" + ]; + repeated string works = 4; +} + +message Pizza { + string size = 1; + repeated string toppings = 2; +} diff --git a/proto/test/schemaregistry/serde/nested.proto b/proto/test/schemaregistry/serde/nested.proto new file mode 100644 index 00000000..3b7ce1b5 --- /dev/null +++ b/proto/test/schemaregistry/serde/nested.proto @@ -0,0 +1,59 @@ +syntax = "proto3"; + +package test; +option go_package="../test"; + +import "google/protobuf/timestamp.proto"; + +message UserId { + oneof user_id { + string kafka_user_id = 1; + int32 other_user_id = 2; + MessageId another_id = 3; + } +} + +message MessageId { + string id = 1; +} + +enum Status { + ACTIVE = 0; + INACTIVE = 1; +} + +message ComplexType { + oneof some_val { + string one_id = 1; + int32 other_id = 2; + } + bool is_active = 3; +} + +/* + * Complex message using nested protos and repeated fields + */ +message NestedMessage { + UserId user_id = 1; + bool is_active = 2; + repeated string experiments_active = 3; + google.protobuf.Timestamp updated_at = 4; + Status status = 5; + ComplexType complex_type = 6; + map map_type = 7; + InnerMessage inner = 8; + + message InnerMessage { + string id = 1 [json_name="id"]; + repeated int32 ids = 2 [packed=true]; + } + + enum InnerEnum { + option allow_alias = true; + ZERO = 0; + ALSO_ZERO = 0; + } + + reserved 14, 15, 9 to 11; + reserved "foo", "bar"; +} diff --git a/proto/test/schemaregistry/serde/newerwidget.proto b/proto/test/schemaregistry/serde/newerwidget.proto new file mode 100644 index 00000000..4243c0eb --- /dev/null +++ b/proto/test/schemaregistry/serde/newerwidget.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +package test; +option go_package="../test"; + +message NewerWidget { + string name = 1; + int32 length = 2; + int32 version = 3; +} diff --git a/proto/test/schemaregistry/serde/newwidget.proto b/proto/test/schemaregistry/serde/newwidget.proto new file mode 100644 index 00000000..fdca7b28 --- /dev/null +++ b/proto/test/schemaregistry/serde/newwidget.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +package test; +option go_package="../test"; + +message NewWidget { + string name = 1; + int32 height = 2; + int32 version = 3; +} diff --git a/proto/test/schemaregistry/serde/test.proto b/proto/test/schemaregistry/serde/test.proto new file mode 100644 index 00000000..28afb444 --- /dev/null +++ b/proto/test/schemaregistry/serde/test.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; + +package test; +option go_package="../test"; + +import "google/protobuf/descriptor.proto"; + +message TestMessage { + string test_string = 1; + bool test_bool = 2; + bytes test_bytes = 3; + double test_double = 4; + float test_float = 5; + fixed32 test_fixed32 = 6; + fixed64 test_fixed64 = 7; + int32 test_int32 = 8; + int64 test_int64 = 9; + sfixed32 test_sfixed32 = 10; + sfixed64 test_sfixed64 = 11; + sint32 test_sint32 = 12; + sint64 test_sint64 = 13; + uint32 test_uint32 = 14; + uint64 test_uint64 = 15; +} \ No newline at end of file diff --git a/proto/test/schemaregistry/serde/widget.proto b/proto/test/schemaregistry/serde/widget.proto new file mode 100644 index 00000000..94a99c2d --- /dev/null +++ b/proto/test/schemaregistry/serde/widget.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +package test; +option go_package="../test"; + +message Widget { + string name = 1; + int32 size = 2; + int32 version = 3; +} diff --git a/schemaregistry/google/type/calendar_period_pb.ts b/schemaregistry/google/type/calendar_period_pb.ts new file mode 100644 index 00000000..a8ad8988 --- /dev/null +++ b/schemaregistry/google/type/calendar_period_pb.ts @@ -0,0 +1,102 @@ +// Copyright 2021-2024 Buf Technologies, Inc. +// +// 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.0.0 with parameter "target=ts" +// @generated from file google/type/calendar_period.proto (package google.type, syntax proto3) +/* eslint-disable */ + +import type { GenEnum, GenFile } from "@bufbuild/protobuf/codegenv1"; +import { enumDesc, fileDesc } from "@bufbuild/protobuf/codegenv1"; + +/** + * Describes the file google/type/calendar_period.proto. + */ +export const file_google_type_calendar_period: GenFile = /*@__PURE__*/ + fileDesc("CiFnb29nbGUvdHlwZS9jYWxlbmRhcl9wZXJpb2QucHJvdG8SC2dvb2dsZS50eXBlKn8KDkNhbGVuZGFyUGVyaW9kEh8KG0NBTEVOREFSX1BFUklPRF9VTlNQRUNJRklFRBAAEgcKA0RBWRABEggKBFdFRUsQAhINCglGT1JUTklHSFQQAxIJCgVNT05USBAEEgsKB1FVQVJURVIQBRIICgRIQUxGEAYSCAoEWUVBUhAHQngKD2NvbS5nb29nbGUudHlwZUITQ2FsZW5kYXJQZXJpb2RQcm90b1ABWkhnb29nbGUuZ29sYW5nLm9yZy9nZW5wcm90by9nb29nbGVhcGlzL3R5cGUvY2FsZW5kYXJwZXJpb2Q7Y2FsZW5kYXJwZXJpb2SiAgNHVFBiBnByb3RvMw"); + +/** + * A `CalendarPeriod` represents the abstract concept of a time period that has + * a canonical start. Grammatically, "the start of the current + * `CalendarPeriod`." All calendar times begin at midnight UTC. + * + * @generated from enum google.type.CalendarPeriod + */ +export enum CalendarPeriod { + /** + * Undefined period, raises an error. + * + * @generated from enum value: CALENDAR_PERIOD_UNSPECIFIED = 0; + */ + CALENDAR_PERIOD_UNSPECIFIED = 0, + + /** + * A day. + * + * @generated from enum value: DAY = 1; + */ + DAY = 1, + + /** + * A week. Weeks begin on Monday, following + * [ISO 8601](https://en.wikipedia.org/wiki/ISO_week_date). + * + * @generated from enum value: WEEK = 2; + */ + WEEK = 2, + + /** + * A fortnight. The first calendar fortnight of the year begins at the start + * of week 1 according to + * [ISO 8601](https://en.wikipedia.org/wiki/ISO_week_date). + * + * @generated from enum value: FORTNIGHT = 3; + */ + FORTNIGHT = 3, + + /** + * A month. + * + * @generated from enum value: MONTH = 4; + */ + MONTH = 4, + + /** + * A quarter. Quarters start on dates 1-Jan, 1-Apr, 1-Jul, and 1-Oct of each + * year. + * + * @generated from enum value: QUARTER = 5; + */ + QUARTER = 5, + + /** + * A half-year. Half-years start on dates 1-Jan and 1-Jul. + * + * @generated from enum value: HALF = 6; + */ + HALF = 6, + + /** + * A year. + * + * @generated from enum value: YEAR = 7; + */ + YEAR = 7, +} + +/** + * Describes the enum google.type.CalendarPeriod. + */ +export const CalendarPeriodSchema: GenEnum = /*@__PURE__*/ + enumDesc(file_google_type_calendar_period, 0); + diff --git a/schemaregistry/google/type/color_pb.ts b/schemaregistry/google/type/color_pb.ts new file mode 100644 index 00000000..462d70da --- /dev/null +++ b/schemaregistry/google/type/color_pb.ts @@ -0,0 +1,204 @@ +// Copyright 2021-2024 Buf Technologies, Inc. +// +// 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.0.0 with parameter "target=ts" +// @generated from file google/type/color.proto (package google.type, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import { file_google_protobuf_wrappers } from "@bufbuild/protobuf/wkt"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/type/color.proto. + */ +export const file_google_type_color: GenFile = /*@__PURE__*/ + fileDesc("Chdnb29nbGUvdHlwZS9jb2xvci5wcm90bxILZ29vZ2xlLnR5cGUiXQoFQ29sb3ISCwoDcmVkGAEgASgCEg0KBWdyZWVuGAIgASgCEgwKBGJsdWUYAyABKAISKgoFYWxwaGEYBCABKAsyGy5nb29nbGUucHJvdG9idWYuRmxvYXRWYWx1ZUJgCg9jb20uZ29vZ2xlLnR5cGVCCkNvbG9yUHJvdG9QAVo2Z29vZ2xlLmdvbGFuZy5vcmcvZ2VucHJvdG8vZ29vZ2xlYXBpcy90eXBlL2NvbG9yO2NvbG9y+AEBogIDR1RQYgZwcm90bzM", [file_google_protobuf_wrappers]); + +/** + * Represents a color in the RGBA color space. This representation is designed + * for simplicity of conversion to/from color representations in various + * languages over compactness. For example, the fields of this representation + * can be trivially provided to the constructor of `java.awt.Color` in Java; it + * can also be trivially provided to UIColor's `+colorWithRed:green:blue:alpha` + * method in iOS; and, with just a little work, it can be easily formatted into + * a CSS `rgba()` string in JavaScript. + * + * This reference page doesn't carry information about the absolute color + * space + * that should be used to interpret the RGB value (e.g. sRGB, Adobe RGB, + * DCI-P3, BT.2020, etc.). By default, applications should assume the sRGB color + * space. + * + * When color equality needs to be decided, implementations, unless + * documented otherwise, treat two colors as equal if all their red, + * green, blue, and alpha values each differ by at most 1e-5. + * + * Example (Java): + * + * import com.google.type.Color; + * + * // ... + * public static java.awt.Color fromProto(Color protocolor) { + * float alpha = protocolor.hasAlpha() + * ? protocolor.getAlpha().getValue() + * : 1.0; + * + * return new java.awt.Color( + * protocolor.getRed(), + * protocolor.getGreen(), + * protocolor.getBlue(), + * alpha); + * } + * + * public static Color toProto(java.awt.Color color) { + * float red = (float) color.getRed(); + * float green = (float) color.getGreen(); + * float blue = (float) color.getBlue(); + * float denominator = 255.0; + * Color.Builder resultBuilder = + * Color + * .newBuilder() + * .setRed(red / denominator) + * .setGreen(green / denominator) + * .setBlue(blue / denominator); + * int alpha = color.getAlpha(); + * if (alpha != 255) { + * result.setAlpha( + * FloatValue + * .newBuilder() + * .setValue(((float) alpha) / denominator) + * .build()); + * } + * return resultBuilder.build(); + * } + * // ... + * + * Example (iOS / Obj-C): + * + * // ... + * static UIColor* fromProto(Color* protocolor) { + * float red = [protocolor red]; + * float green = [protocolor green]; + * float blue = [protocolor blue]; + * FloatValue* alpha_wrapper = [protocolor alpha]; + * float alpha = 1.0; + * if (alpha_wrapper != nil) { + * alpha = [alpha_wrapper value]; + * } + * return [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; + * } + * + * static Color* toProto(UIColor* color) { + * CGFloat red, green, blue, alpha; + * if (![color getRed:&red green:&green blue:&blue alpha:&alpha]) { + * return nil; + * } + * Color* result = [[Color alloc] init]; + * [result setRed:red]; + * [result setGreen:green]; + * [result setBlue:blue]; + * if (alpha <= 0.9999) { + * [result setAlpha:floatWrapperWithValue(alpha)]; + * } + * [result autorelease]; + * return result; + * } + * // ... + * + * Example (JavaScript): + * + * // ... + * + * var protoToCssColor = function(rgb_color) { + * var redFrac = rgb_color.red || 0.0; + * var greenFrac = rgb_color.green || 0.0; + * var blueFrac = rgb_color.blue || 0.0; + * var red = Math.floor(redFrac * 255); + * var green = Math.floor(greenFrac * 255); + * var blue = Math.floor(blueFrac * 255); + * + * if (!('alpha' in rgb_color)) { + * return rgbToCssColor(red, green, blue); + * } + * + * var alphaFrac = rgb_color.alpha.value || 0.0; + * var rgbParams = [red, green, blue].join(','); + * return ['rgba(', rgbParams, ',', alphaFrac, ')'].join(''); + * }; + * + * var rgbToCssColor = function(red, green, blue) { + * var rgbNumber = new Number((red << 16) | (green << 8) | blue); + * var hexString = rgbNumber.toString(16); + * var missingZeros = 6 - hexString.length; + * var resultBuilder = ['#']; + * for (var i = 0; i < missingZeros; i++) { + * resultBuilder.push('0'); + * } + * resultBuilder.push(hexString); + * return resultBuilder.join(''); + * }; + * + * // ... + * + * @generated from message google.type.Color + */ +export type Color = Message<"google.type.Color"> & { + /** + * The amount of red in the color as a value in the interval [0, 1]. + * + * @generated from field: float red = 1; + */ + red: number; + + /** + * The amount of green in the color as a value in the interval [0, 1]. + * + * @generated from field: float green = 2; + */ + green: number; + + /** + * The amount of blue in the color as a value in the interval [0, 1]. + * + * @generated from field: float blue = 3; + */ + blue: number; + + /** + * The fraction of this color that should be applied to the pixel. That is, + * the final pixel color is defined by the equation: + * + * `pixel color = alpha * (this color) + (1.0 - alpha) * (background color)` + * + * This means that a value of 1.0 corresponds to a solid color, whereas + * a value of 0.0 corresponds to a completely transparent color. This + * uses a wrapper message rather than a simple float scalar so that it is + * possible to distinguish between a default value and the value being unset. + * If omitted, this color object is rendered as a solid color + * (as if the alpha value had been explicitly given a value of 1.0). + * + * @generated from field: google.protobuf.FloatValue alpha = 4; + */ + alpha?: number; +}; + +/** + * Describes the message google.type.Color. + * Use `create(ColorSchema)` to create a new message. + */ +export const ColorSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_type_color, 0); + diff --git a/schemaregistry/google/type/date_pb.ts b/schemaregistry/google/type/date_pb.ts new file mode 100644 index 00000000..eaf34962 --- /dev/null +++ b/schemaregistry/google/type/date_pb.ts @@ -0,0 +1,79 @@ +// Copyright 2021-2024 Buf Technologies, Inc. +// +// 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.0.0 with parameter "target=ts" +// @generated from file google/type/date.proto (package google.type, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/type/date.proto. + */ +export const file_google_type_date: GenFile = /*@__PURE__*/ + fileDesc("ChZnb29nbGUvdHlwZS9kYXRlLnByb3RvEgtnb29nbGUudHlwZSIwCgREYXRlEgwKBHllYXIYASABKAUSDQoFbW9udGgYAiABKAUSCwoDZGF5GAMgASgFQl0KD2NvbS5nb29nbGUudHlwZUIJRGF0ZVByb3RvUAFaNGdvb2dsZS5nb2xhbmcub3JnL2dlbnByb3RvL2dvb2dsZWFwaXMvdHlwZS9kYXRlO2RhdGX4AQGiAgNHVFBiBnByb3RvMw"); + +/** + * Represents a whole or partial calendar date, such as a birthday. The time of + * day and time zone are either specified elsewhere or are insignificant. The + * date is relative to the Gregorian Calendar. This can represent one of the + * following: + * + * * A full date, with non-zero year, month, and day values + * * A month and day value, with a zero year, such as an anniversary + * * A year on its own, with zero month and day values + * * A year and month value, with a zero day, such as a credit card expiration + * date + * + * Related types are [google.type.TimeOfDay][google.type.TimeOfDay] and + * `google.protobuf.Timestamp`. + * + * @generated from message google.type.Date + */ +export type Date = Message<"google.type.Date"> & { + /** + * Year of the date. Must be from 1 to 9999, or 0 to specify a date without + * a year. + * + * @generated from field: int32 year = 1; + */ + year: number; + + /** + * Month of a year. Must be from 1 to 12, or 0 to specify a year without a + * month and day. + * + * @generated from field: int32 month = 2; + */ + month: number; + + /** + * Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 + * to specify a year by itself or a year and month where the day isn't + * significant. + * + * @generated from field: int32 day = 3; + */ + day: number; +}; + +/** + * Describes the message google.type.Date. + * Use `create(DateSchema)` to create a new message. + */ +export const DateSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_type_date, 0); + diff --git a/schemaregistry/google/type/datetime_pb.ts b/schemaregistry/google/type/datetime_pb.ts new file mode 100644 index 00000000..511b0859 --- /dev/null +++ b/schemaregistry/google/type/datetime_pb.ts @@ -0,0 +1,180 @@ +// Copyright 2021-2024 Buf Technologies, Inc. +// +// 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.0.0 with parameter "target=ts" +// @generated from file google/type/datetime.proto (package google.type, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { Duration } from "@bufbuild/protobuf/wkt"; +import { file_google_protobuf_duration } from "@bufbuild/protobuf/wkt"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/type/datetime.proto. + */ +export const file_google_type_datetime: GenFile = /*@__PURE__*/ + fileDesc("Chpnb29nbGUvdHlwZS9kYXRldGltZS5wcm90bxILZ29vZ2xlLnR5cGUi4AEKCERhdGVUaW1lEgwKBHllYXIYASABKAUSDQoFbW9udGgYAiABKAUSCwoDZGF5GAMgASgFEg0KBWhvdXJzGAQgASgFEg8KB21pbnV0ZXMYBSABKAUSDwoHc2Vjb25kcxgGIAEoBRINCgVuYW5vcxgHIAEoBRIvCgp1dGNfb2Zmc2V0GAggASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uSAASKgoJdGltZV96b25lGAkgASgLMhUuZ29vZ2xlLnR5cGUuVGltZVpvbmVIAEINCgt0aW1lX29mZnNldCInCghUaW1lWm9uZRIKCgJpZBgBIAEoCRIPCgd2ZXJzaW9uGAIgASgJQmkKD2NvbS5nb29nbGUudHlwZUINRGF0ZVRpbWVQcm90b1ABWjxnb29nbGUuZ29sYW5nLm9yZy9nZW5wcm90by9nb29nbGVhcGlzL3R5cGUvZGF0ZXRpbWU7ZGF0ZXRpbWX4AQGiAgNHVFBiBnByb3RvMw", [file_google_protobuf_duration]); + +/** + * Represents civil time (or occasionally physical time). + * + * This type can represent a civil time in one of a few possible ways: + * + * * When utc_offset is set and time_zone is unset: a civil time on a calendar + * day with a particular offset from UTC. + * * When time_zone is set and utc_offset is unset: a civil time on a calendar + * day in a particular time zone. + * * When neither time_zone nor utc_offset is set: a civil time on a calendar + * day in local time. + * + * The date is relative to the Proleptic Gregorian Calendar. + * + * If year is 0, the DateTime is considered not to have a specific year. month + * and day must have valid, non-zero values. + * + * This type may also be used to represent a physical time if all the date and + * time fields are set and either case of the `time_offset` oneof is set. + * Consider using `Timestamp` message for physical time instead. If your use + * case also would like to store the user's timezone, that can be done in + * another field. + * + * This type is more flexible than some applications may want. Make sure to + * document and validate your application's limitations. + * + * @generated from message google.type.DateTime + */ +export type DateTime = Message<"google.type.DateTime"> & { + /** + * Optional. Year of date. Must be from 1 to 9999, or 0 if specifying a + * datetime without a year. + * + * @generated from field: int32 year = 1; + */ + year: number; + + /** + * Required. Month of year. Must be from 1 to 12. + * + * @generated from field: int32 month = 2; + */ + month: number; + + /** + * Required. Day of month. Must be from 1 to 31 and valid for the year and + * month. + * + * @generated from field: int32 day = 3; + */ + day: number; + + /** + * Required. Hours of day in 24 hour format. Should be from 0 to 23. An API + * may choose to allow the value "24:00:00" for scenarios like business + * closing time. + * + * @generated from field: int32 hours = 4; + */ + hours: number; + + /** + * Required. Minutes of hour of day. Must be from 0 to 59. + * + * @generated from field: int32 minutes = 5; + */ + minutes: number; + + /** + * Required. Seconds of minutes of the time. Must normally be from 0 to 59. An + * API may allow the value 60 if it allows leap-seconds. + * + * @generated from field: int32 seconds = 6; + */ + seconds: number; + + /** + * Required. Fractions of seconds in nanoseconds. Must be from 0 to + * 999,999,999. + * + * @generated from field: int32 nanos = 7; + */ + nanos: number; + + /** + * Optional. Specifies either the UTC offset or the time zone of the DateTime. + * Choose carefully between them, considering that time zone data may change + * in the future (for example, a country modifies their DST start/end dates, + * and future DateTimes in the affected range had already been stored). + * If omitted, the DateTime is considered to be in local time. + * + * @generated from oneof google.type.DateTime.time_offset + */ + timeOffset: { + /** + * UTC offset. Must be whole seconds, between -18 hours and +18 hours. + * For example, a UTC offset of -4:00 would be represented as + * { seconds: -14400 }. + * + * @generated from field: google.protobuf.Duration utc_offset = 8; + */ + value: Duration; + case: "utcOffset"; + } | { + /** + * Time zone. + * + * @generated from field: google.type.TimeZone time_zone = 9; + */ + value: TimeZone; + case: "timeZone"; + } | { case: undefined; value?: undefined }; +}; + +/** + * Describes the message google.type.DateTime. + * Use `create(DateTimeSchema)` to create a new message. + */ +export const DateTimeSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_type_datetime, 0); + +/** + * Represents a time zone from the + * [IANA Time Zone Database](https://www.iana.org/time-zones). + * + * @generated from message google.type.TimeZone + */ +export type TimeZone = Message<"google.type.TimeZone"> & { + /** + * IANA Time Zone Database time zone, e.g. "America/New_York". + * + * @generated from field: string id = 1; + */ + id: string; + + /** + * Optional. IANA Time Zone Database version number, e.g. "2019a". + * + * @generated from field: string version = 2; + */ + version: string; +}; + +/** + * Describes the message google.type.TimeZone. + * Use `create(TimeZoneSchema)` to create a new message. + */ +export const TimeZoneSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_type_datetime, 1); + diff --git a/schemaregistry/google/type/dayofweek_pb.ts b/schemaregistry/google/type/dayofweek_pb.ts new file mode 100644 index 00000000..8932990c --- /dev/null +++ b/schemaregistry/google/type/dayofweek_pb.ts @@ -0,0 +1,96 @@ +// Copyright 2021-2024 Buf Technologies, Inc. +// +// 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.0.0 with parameter "target=ts" +// @generated from file google/type/dayofweek.proto (package google.type, syntax proto3) +/* eslint-disable */ + +import type { GenEnum, GenFile } from "@bufbuild/protobuf/codegenv1"; +import { enumDesc, fileDesc } from "@bufbuild/protobuf/codegenv1"; + +/** + * Describes the file google/type/dayofweek.proto. + */ +export const file_google_type_dayofweek: GenFile = /*@__PURE__*/ + fileDesc("Chtnb29nbGUvdHlwZS9kYXlvZndlZWsucHJvdG8SC2dvb2dsZS50eXBlKoQBCglEYXlPZldlZWsSGwoXREFZX09GX1dFRUtfVU5TUEVDSUZJRUQQABIKCgZNT05EQVkQARILCgdUVUVTREFZEAISDQoJV0VETkVTREFZEAMSDAoIVEhVUlNEQVkQBBIKCgZGUklEQVkQBRIMCghTQVRVUkRBWRAGEgoKBlNVTkRBWRAHQmkKD2NvbS5nb29nbGUudHlwZUIORGF5T2ZXZWVrUHJvdG9QAVo+Z29vZ2xlLmdvbGFuZy5vcmcvZ2VucHJvdG8vZ29vZ2xlYXBpcy90eXBlL2RheW9md2VlaztkYXlvZndlZWuiAgNHVFBiBnByb3RvMw"); + +/** + * Represents a day of the week. + * + * @generated from enum google.type.DayOfWeek + */ +export enum DayOfWeek { + /** + * The day of the week is unspecified. + * + * @generated from enum value: DAY_OF_WEEK_UNSPECIFIED = 0; + */ + DAY_OF_WEEK_UNSPECIFIED = 0, + + /** + * Monday + * + * @generated from enum value: MONDAY = 1; + */ + MONDAY = 1, + + /** + * Tuesday + * + * @generated from enum value: TUESDAY = 2; + */ + TUESDAY = 2, + + /** + * Wednesday + * + * @generated from enum value: WEDNESDAY = 3; + */ + WEDNESDAY = 3, + + /** + * Thursday + * + * @generated from enum value: THURSDAY = 4; + */ + THURSDAY = 4, + + /** + * Friday + * + * @generated from enum value: FRIDAY = 5; + */ + FRIDAY = 5, + + /** + * Saturday + * + * @generated from enum value: SATURDAY = 6; + */ + SATURDAY = 6, + + /** + * Sunday + * + * @generated from enum value: SUNDAY = 7; + */ + SUNDAY = 7, +} + +/** + * Describes the enum google.type.DayOfWeek. + */ +export const DayOfWeekSchema: GenEnum = /*@__PURE__*/ + enumDesc(file_google_type_dayofweek, 0); + diff --git a/schemaregistry/google/type/decimal_pb.ts b/schemaregistry/google/type/decimal_pb.ts new file mode 100644 index 00000000..f3c65377 --- /dev/null +++ b/schemaregistry/google/type/decimal_pb.ts @@ -0,0 +1,114 @@ +// Copyright 2021-2024 Buf Technologies, Inc. +// +// 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.0.0 with parameter "target=ts" +// @generated from file google/type/decimal.proto (package google.type, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/type/decimal.proto. + */ +export const file_google_type_decimal: GenFile = /*@__PURE__*/ + fileDesc("Chlnb29nbGUvdHlwZS9kZWNpbWFsLnByb3RvEgtnb29nbGUudHlwZSIYCgdEZWNpbWFsEg0KBXZhbHVlGAEgASgJQmYKD2NvbS5nb29nbGUudHlwZUIMRGVjaW1hbFByb3RvUAFaOmdvb2dsZS5nb2xhbmcub3JnL2dlbnByb3RvL2dvb2dsZWFwaXMvdHlwZS9kZWNpbWFsO2RlY2ltYWz4AQGiAgNHVFBiBnByb3RvMw"); + +/** + * A representation of a decimal value, such as 2.5. Clients may convert values + * into language-native decimal formats, such as Java's [BigDecimal][] or + * Python's [decimal.Decimal][]. + * + * [BigDecimal]: + * https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/math/BigDecimal.html + * [decimal.Decimal]: https://docs.python.org/3/library/decimal.html + * + * @generated from message google.type.Decimal + */ +export type Decimal = Message<"google.type.Decimal"> & { + /** + * The decimal value, as a string. + * + * The string representation consists of an optional sign, `+` (`U+002B`) + * or `-` (`U+002D`), followed by a sequence of zero or more decimal digits + * ("the integer"), optionally followed by a fraction, optionally followed + * by an exponent. + * + * The fraction consists of a decimal point followed by zero or more decimal + * digits. The string must contain at least one digit in either the integer + * or the fraction. The number formed by the sign, the integer and the + * fraction is referred to as the significand. + * + * The exponent consists of the character `e` (`U+0065`) or `E` (`U+0045`) + * followed by one or more decimal digits. + * + * Services **should** normalize decimal values before storing them by: + * + * - Removing an explicitly-provided `+` sign (`+2.5` -> `2.5`). + * - Replacing a zero-length integer value with `0` (`.5` -> `0.5`). + * - Coercing the exponent character to lower-case (`2.5E8` -> `2.5e8`). + * - Removing an explicitly-provided zero exponent (`2.5e0` -> `2.5`). + * + * Services **may** perform additional normalization based on its own needs + * and the internal decimal implementation selected, such as shifting the + * decimal point and exponent value together (example: `2.5e-1` <-> `0.25`). + * Additionally, services **may** preserve trailing zeroes in the fraction + * to indicate increased precision, but are not required to do so. + * + * Note that only the `.` character is supported to divide the integer + * and the fraction; `,` **should not** be supported regardless of locale. + * Additionally, thousand separators **should not** be supported. If a + * service does support them, values **must** be normalized. + * + * The ENBF grammar is: + * + * DecimalString = + * [Sign] Significand [Exponent]; + * + * Sign = '+' | '-'; + * + * Significand = + * Digits ['.'] [Digits] | [Digits] '.' Digits; + * + * Exponent = ('e' | 'E') [Sign] Digits; + * + * Digits = { '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' }; + * + * Services **should** clearly document the range of supported values, the + * maximum supported precision (total number of digits), and, if applicable, + * the scale (number of digits after the decimal point), as well as how it + * behaves when receiving out-of-bounds values. + * + * Services **may** choose to accept values passed as input even when the + * value has a higher precision or scale than the service supports, and + * **should** round the value to fit the supported scale. Alternatively, the + * service **may** error with `400 Bad Request` (`INVALID_ARGUMENT` in gRPC) + * if precision would be lost. + * + * Services **should** error with `400 Bad Request` (`INVALID_ARGUMENT` in + * gRPC) if the service receives a value outside of the supported range. + * + * @generated from field: string value = 1; + */ + value: string; +}; + +/** + * Describes the message google.type.Decimal. + * Use `create(DecimalSchema)` to create a new message. + */ +export const DecimalSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_type_decimal, 0); + diff --git a/schemaregistry/google/type/expr_pb.ts b/schemaregistry/google/type/expr_pb.ts new file mode 100644 index 00000000..a4dd114b --- /dev/null +++ b/schemaregistry/google/type/expr_pb.ts @@ -0,0 +1,105 @@ +// Copyright 2021-2024 Buf Technologies, Inc. +// +// 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.0.0 with parameter "target=ts" +// @generated from file google/type/expr.proto (package google.type, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/type/expr.proto. + */ +export const file_google_type_expr: GenFile = /*@__PURE__*/ + fileDesc("ChZnb29nbGUvdHlwZS9leHByLnByb3RvEgtnb29nbGUudHlwZSJQCgRFeHByEhIKCmV4cHJlc3Npb24YASABKAkSDQoFdGl0bGUYAiABKAkSEwoLZGVzY3JpcHRpb24YAyABKAkSEAoIbG9jYXRpb24YBCABKAlCWgoPY29tLmdvb2dsZS50eXBlQglFeHByUHJvdG9QAVo0Z29vZ2xlLmdvbGFuZy5vcmcvZ2VucHJvdG8vZ29vZ2xlYXBpcy90eXBlL2V4cHI7ZXhwcqICA0dUUGIGcHJvdG8z"); + +/** + * Represents a textual expression in the Common Expression Language (CEL) + * syntax. CEL is a C-like expression language. The syntax and semantics of CEL + * are documented at https://github.com/google/cel-spec. + * + * Example (Comparison): + * + * title: "Summary size limit" + * description: "Determines if a summary is less than 100 chars" + * expression: "document.summary.size() < 100" + * + * Example (Equality): + * + * title: "Requestor is owner" + * description: "Determines if requestor is the document owner" + * expression: "document.owner == request.auth.claims.email" + * + * Example (Logic): + * + * title: "Public documents" + * description: "Determine whether the document should be publicly visible" + * expression: "document.type != 'private' && document.type != 'internal'" + * + * Example (Data Manipulation): + * + * title: "Notification string" + * description: "Create a notification string with a timestamp." + * expression: "'New message received at ' + string(document.create_time)" + * + * The exact variables and functions that may be referenced within an expression + * are determined by the service that evaluates it. See the service + * documentation for additional information. + * + * @generated from message google.type.Expr + */ +export type Expr = Message<"google.type.Expr"> & { + /** + * Textual representation of an expression in Common Expression Language + * syntax. + * + * @generated from field: string expression = 1; + */ + expression: string; + + /** + * Optional. Title for the expression, i.e. a short string describing + * its purpose. This can be used e.g. in UIs which allow to enter the + * expression. + * + * @generated from field: string title = 2; + */ + title: string; + + /** + * Optional. Description of the expression. This is a longer text which + * describes the expression, e.g. when hovered over it in a UI. + * + * @generated from field: string description = 3; + */ + description: string; + + /** + * Optional. String indicating the location of the expression for error + * reporting, e.g. a file name and a position in the file. + * + * @generated from field: string location = 4; + */ + location: string; +}; + +/** + * Describes the message google.type.Expr. + * Use `create(ExprSchema)` to create a new message. + */ +export const ExprSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_type_expr, 0); + diff --git a/schemaregistry/google/type/fraction_pb.ts b/schemaregistry/google/type/fraction_pb.ts new file mode 100644 index 00000000..2d180530 --- /dev/null +++ b/schemaregistry/google/type/fraction_pb.ts @@ -0,0 +1,57 @@ +// Copyright 2021-2024 Buf Technologies, Inc. +// +// 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.0.0 with parameter "target=ts" +// @generated from file google/type/fraction.proto (package google.type, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/type/fraction.proto. + */ +export const file_google_type_fraction: GenFile = /*@__PURE__*/ + fileDesc("Chpnb29nbGUvdHlwZS9mcmFjdGlvbi5wcm90bxILZ29vZ2xlLnR5cGUiMgoIRnJhY3Rpb24SEQoJbnVtZXJhdG9yGAEgASgDEhMKC2Rlbm9taW5hdG9yGAIgASgDQmYKD2NvbS5nb29nbGUudHlwZUINRnJhY3Rpb25Qcm90b1ABWjxnb29nbGUuZ29sYW5nLm9yZy9nZW5wcm90by9nb29nbGVhcGlzL3R5cGUvZnJhY3Rpb247ZnJhY3Rpb26iAgNHVFBiBnByb3RvMw"); + +/** + * Represents a fraction in terms of a numerator divided by a denominator. + * + * @generated from message google.type.Fraction + */ +export type Fraction = Message<"google.type.Fraction"> & { + /** + * The numerator in the fraction, e.g. 2 in 2/3. + * + * @generated from field: int64 numerator = 1; + */ + numerator: bigint; + + /** + * The value by which the numerator is divided, e.g. 3 in 2/3. Must be + * positive. + * + * @generated from field: int64 denominator = 2; + */ + denominator: bigint; +}; + +/** + * Describes the message google.type.Fraction. + * Use `create(FractionSchema)` to create a new message. + */ +export const FractionSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_type_fraction, 0); + diff --git a/schemaregistry/google/type/interval_pb.ts b/schemaregistry/google/type/interval_pb.ts new file mode 100644 index 00000000..ae5ffa96 --- /dev/null +++ b/schemaregistry/google/type/interval_pb.ts @@ -0,0 +1,69 @@ +// Copyright 2021-2024 Buf Technologies, Inc. +// +// 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.0.0 with parameter "target=ts" +// @generated from file google/type/interval.proto (package google.type, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { Timestamp } from "@bufbuild/protobuf/wkt"; +import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/type/interval.proto. + */ +export const file_google_type_interval: GenFile = /*@__PURE__*/ + fileDesc("Chpnb29nbGUvdHlwZS9pbnRlcnZhbC5wcm90bxILZ29vZ2xlLnR5cGUiaAoISW50ZXJ2YWwSLgoKc3RhcnRfdGltZRgBIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLAoIZW5kX3RpbWUYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQmkKD2NvbS5nb29nbGUudHlwZUINSW50ZXJ2YWxQcm90b1ABWjxnb29nbGUuZ29sYW5nLm9yZy9nZW5wcm90by9nb29nbGVhcGlzL3R5cGUvaW50ZXJ2YWw7aW50ZXJ2YWz4AQGiAgNHVFBiBnByb3RvMw", [file_google_protobuf_timestamp]); + +/** + * Represents a time interval, encoded as a Timestamp start (inclusive) and a + * Timestamp end (exclusive). + * + * The start must be less than or equal to the end. + * When the start equals the end, the interval is empty (matches no time). + * When both start and end are unspecified, the interval matches any time. + * + * @generated from message google.type.Interval + */ +export type Interval = Message<"google.type.Interval"> & { + /** + * Optional. Inclusive start of the interval. + * + * If specified, a Timestamp matching this interval will have to be the same + * or after the start. + * + * @generated from field: google.protobuf.Timestamp start_time = 1; + */ + startTime?: Timestamp; + + /** + * Optional. Exclusive end of the interval. + * + * If specified, a Timestamp matching this interval will have to be before the + * end. + * + * @generated from field: google.protobuf.Timestamp end_time = 2; + */ + endTime?: Timestamp; +}; + +/** + * Describes the message google.type.Interval. + * Use `create(IntervalSchema)` to create a new message. + */ +export const IntervalSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_type_interval, 0); + diff --git a/schemaregistry/google/type/latlng_pb.ts b/schemaregistry/google/type/latlng_pb.ts new file mode 100644 index 00000000..41c99c15 --- /dev/null +++ b/schemaregistry/google/type/latlng_pb.ts @@ -0,0 +1,60 @@ +// Copyright 2021-2024 Buf Technologies, Inc. +// +// 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.0.0 with parameter "target=ts" +// @generated from file google/type/latlng.proto (package google.type, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/type/latlng.proto. + */ +export const file_google_type_latlng: GenFile = /*@__PURE__*/ + fileDesc("Chhnb29nbGUvdHlwZS9sYXRsbmcucHJvdG8SC2dvb2dsZS50eXBlIi0KBkxhdExuZxIQCghsYXRpdHVkZRgBIAEoARIRCglsb25naXR1ZGUYAiABKAFCYwoPY29tLmdvb2dsZS50eXBlQgtMYXRMbmdQcm90b1ABWjhnb29nbGUuZ29sYW5nLm9yZy9nZW5wcm90by9nb29nbGVhcGlzL3R5cGUvbGF0bG5nO2xhdGxuZ/gBAaICA0dUUGIGcHJvdG8z"); + +/** + * An object that represents a latitude/longitude pair. This is expressed as a + * pair of doubles to represent degrees latitude and degrees longitude. Unless + * specified otherwise, this must conform to the + * WGS84 + * standard. Values must be within normalized ranges. + * + * @generated from message google.type.LatLng + */ +export type LatLng = Message<"google.type.LatLng"> & { + /** + * The latitude in degrees. It must be in the range [-90.0, +90.0]. + * + * @generated from field: double latitude = 1; + */ + latitude: number; + + /** + * The longitude in degrees. It must be in the range [-180.0, +180.0]. + * + * @generated from field: double longitude = 2; + */ + longitude: number; +}; + +/** + * Describes the message google.type.LatLng. + * Use `create(LatLngSchema)` to create a new message. + */ +export const LatLngSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_type_latlng, 0); + diff --git a/schemaregistry/google/type/localized_text_pb.ts b/schemaregistry/google/type/localized_text_pb.ts new file mode 100644 index 00000000..80235333 --- /dev/null +++ b/schemaregistry/google/type/localized_text_pb.ts @@ -0,0 +1,59 @@ +// Copyright 2021-2024 Buf Technologies, Inc. +// +// 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.0.0 with parameter "target=ts" +// @generated from file google/type/localized_text.proto (package google.type, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/type/localized_text.proto. + */ +export const file_google_type_localized_text: GenFile = /*@__PURE__*/ + fileDesc("CiBnb29nbGUvdHlwZS9sb2NhbGl6ZWRfdGV4dC5wcm90bxILZ29vZ2xlLnR5cGUiNAoNTG9jYWxpemVkVGV4dBIMCgR0ZXh0GAEgASgJEhUKDWxhbmd1YWdlX2NvZGUYAiABKAlCegoPY29tLmdvb2dsZS50eXBlQhJMb2NhbGl6ZWRUZXh0UHJvdG9QAVpIZ29vZ2xlLmdvbGFuZy5vcmcvZ2VucHJvdG8vZ29vZ2xlYXBpcy90eXBlL2xvY2FsaXplZF90ZXh0O2xvY2FsaXplZF90ZXh0+AEBogIDR1RQYgZwcm90bzM"); + +/** + * Localized variant of a text in a particular language. + * + * @generated from message google.type.LocalizedText + */ +export type LocalizedText = Message<"google.type.LocalizedText"> & { + /** + * Localized string in the language corresponding to `language_code' below. + * + * @generated from field: string text = 1; + */ + text: string; + + /** + * The text's BCP-47 language code, such as "en-US" or "sr-Latn". + * + * For more information, see + * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. + * + * @generated from field: string language_code = 2; + */ + languageCode: string; +}; + +/** + * Describes the message google.type.LocalizedText. + * Use `create(LocalizedTextSchema)` to create a new message. + */ +export const LocalizedTextSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_type_localized_text, 0); + diff --git a/schemaregistry/google/type/money_pb.ts b/schemaregistry/google/type/money_pb.ts new file mode 100644 index 00000000..de6bd31d --- /dev/null +++ b/schemaregistry/google/type/money_pb.ts @@ -0,0 +1,69 @@ +// Copyright 2021-2024 Buf Technologies, Inc. +// +// 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.0.0 with parameter "target=ts" +// @generated from file google/type/money.proto (package google.type, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/type/money.proto. + */ +export const file_google_type_money: GenFile = /*@__PURE__*/ + fileDesc("Chdnb29nbGUvdHlwZS9tb25leS5wcm90bxILZ29vZ2xlLnR5cGUiPAoFTW9uZXkSFQoNY3VycmVuY3lfY29kZRgBIAEoCRINCgV1bml0cxgCIAEoAxINCgVuYW5vcxgDIAEoBUJgCg9jb20uZ29vZ2xlLnR5cGVCCk1vbmV5UHJvdG9QAVo2Z29vZ2xlLmdvbGFuZy5vcmcvZ2VucHJvdG8vZ29vZ2xlYXBpcy90eXBlL21vbmV5O21vbmV5+AEBogIDR1RQYgZwcm90bzM"); + +/** + * Represents an amount of money with its currency type. + * + * @generated from message google.type.Money + */ +export type Money = Message<"google.type.Money"> & { + /** + * The three-letter currency code defined in ISO 4217. + * + * @generated from field: string currency_code = 1; + */ + currencyCode: string; + + /** + * The whole units of the amount. + * For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar. + * + * @generated from field: int64 units = 2; + */ + units: bigint; + + /** + * Number of nano (10^-9) units of the amount. + * The value must be between -999,999,999 and +999,999,999 inclusive. + * If `units` is positive, `nanos` must be positive or zero. + * If `units` is zero, `nanos` can be positive, zero, or negative. + * If `units` is negative, `nanos` must be negative or zero. + * For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000. + * + * @generated from field: int32 nanos = 3; + */ + nanos: number; +}; + +/** + * Describes the message google.type.Money. + * Use `create(MoneySchema)` to create a new message. + */ +export const MoneySchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_type_money, 0); + diff --git a/schemaregistry/google/type/month_pb.ts b/schemaregistry/google/type/month_pb.ts new file mode 100644 index 00000000..072f60b1 --- /dev/null +++ b/schemaregistry/google/type/month_pb.ts @@ -0,0 +1,131 @@ +// Copyright 2021-2024 Buf Technologies, Inc. +// +// 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.0.0 with parameter "target=ts" +// @generated from file google/type/month.proto (package google.type, syntax proto3) +/* eslint-disable */ + +import type { GenEnum, GenFile } from "@bufbuild/protobuf/codegenv1"; +import { enumDesc, fileDesc } from "@bufbuild/protobuf/codegenv1"; + +/** + * Describes the file google/type/month.proto. + */ +export const file_google_type_month: GenFile = /*@__PURE__*/ + fileDesc("Chdnb29nbGUvdHlwZS9tb250aC5wcm90bxILZ29vZ2xlLnR5cGUqsAEKBU1vbnRoEhUKEU1PTlRIX1VOU1BFQ0lGSUVEEAASCwoHSkFOVUFSWRABEgwKCEZFQlJVQVJZEAISCQoFTUFSQ0gQAxIJCgVBUFJJTBAEEgcKA01BWRAFEggKBEpVTkUQBhIICgRKVUxZEAcSCgoGQVVHVVNUEAgSDQoJU0VQVEVNQkVSEAkSCwoHT0NUT0JFUhAKEgwKCE5PVkVNQkVSEAsSDAoIREVDRU1CRVIQDEJdCg9jb20uZ29vZ2xlLnR5cGVCCk1vbnRoUHJvdG9QAVo2Z29vZ2xlLmdvbGFuZy5vcmcvZ2VucHJvdG8vZ29vZ2xlYXBpcy90eXBlL21vbnRoO21vbnRoogIDR1RQYgZwcm90bzM"); + +/** + * Represents a month in the Gregorian calendar. + * + * @generated from enum google.type.Month + */ +export enum Month { + /** + * The unspecified month. + * + * @generated from enum value: MONTH_UNSPECIFIED = 0; + */ + MONTH_UNSPECIFIED = 0, + + /** + * The month of January. + * + * @generated from enum value: JANUARY = 1; + */ + JANUARY = 1, + + /** + * The month of February. + * + * @generated from enum value: FEBRUARY = 2; + */ + FEBRUARY = 2, + + /** + * The month of March. + * + * @generated from enum value: MARCH = 3; + */ + MARCH = 3, + + /** + * The month of April. + * + * @generated from enum value: APRIL = 4; + */ + APRIL = 4, + + /** + * The month of May. + * + * @generated from enum value: MAY = 5; + */ + MAY = 5, + + /** + * The month of June. + * + * @generated from enum value: JUNE = 6; + */ + JUNE = 6, + + /** + * The month of July. + * + * @generated from enum value: JULY = 7; + */ + JULY = 7, + + /** + * The month of August. + * + * @generated from enum value: AUGUST = 8; + */ + AUGUST = 8, + + /** + * The month of September. + * + * @generated from enum value: SEPTEMBER = 9; + */ + SEPTEMBER = 9, + + /** + * The month of October. + * + * @generated from enum value: OCTOBER = 10; + */ + OCTOBER = 10, + + /** + * The month of November. + * + * @generated from enum value: NOVEMBER = 11; + */ + NOVEMBER = 11, + + /** + * The month of December. + * + * @generated from enum value: DECEMBER = 12; + */ + DECEMBER = 12, +} + +/** + * Describes the enum google.type.Month. + */ +export const MonthSchema: GenEnum = /*@__PURE__*/ + enumDesc(file_google_type_month, 0); + diff --git a/schemaregistry/google/type/phone_number_pb.ts b/schemaregistry/google/type/phone_number_pb.ts new file mode 100644 index 00000000..f11e0e54 --- /dev/null +++ b/schemaregistry/google/type/phone_number_pb.ts @@ -0,0 +1,165 @@ +// Copyright 2021-2024 Buf Technologies, Inc. +// +// 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.0.0 with parameter "target=ts" +// @generated from file google/type/phone_number.proto (package google.type, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/type/phone_number.proto. + */ +export const file_google_type_phone_number: GenFile = /*@__PURE__*/ + fileDesc("Ch5nb29nbGUvdHlwZS9waG9uZV9udW1iZXIucHJvdG8SC2dvb2dsZS50eXBlIqsBCgtQaG9uZU51bWJlchIVCgtlMTY0X251bWJlchgBIAEoCUgAEjgKCnNob3J0X2NvZGUYAiABKAsyIi5nb29nbGUudHlwZS5QaG9uZU51bWJlci5TaG9ydENvZGVIABIRCglleHRlbnNpb24YAyABKAkaMAoJU2hvcnRDb2RlEhMKC3JlZ2lvbl9jb2RlGAEgASgJEg4KBm51bWJlchgCIAEoCUIGCgRraW5kQnQKD2NvbS5nb29nbGUudHlwZUIQUGhvbmVOdW1iZXJQcm90b1ABWkRnb29nbGUuZ29sYW5nLm9yZy9nZW5wcm90by9nb29nbGVhcGlzL3R5cGUvcGhvbmVfbnVtYmVyO3Bob25lX251bWJlcvgBAaICA0dUUGIGcHJvdG8z"); + +/** + * An object representing a phone number, suitable as an API wire format. + * + * This representation: + * + * - should not be used for locale-specific formatting of a phone number, such + * as "+1 (650) 253-0000 ext. 123" + * + * - is not designed for efficient storage + * - may not be suitable for dialing - specialized libraries (see references) + * should be used to parse the number for that purpose + * + * To do something meaningful with this number, such as format it for various + * use-cases, convert it to an `i18n.phonenumbers.PhoneNumber` object first. + * + * For instance, in Java this would be: + * + * com.google.type.PhoneNumber wireProto = + * com.google.type.PhoneNumber.newBuilder().build(); + * com.google.i18n.phonenumbers.Phonenumber.PhoneNumber phoneNumber = + * PhoneNumberUtil.getInstance().parse(wireProto.getE164Number(), "ZZ"); + * if (!wireProto.getExtension().isEmpty()) { + * phoneNumber.setExtension(wireProto.getExtension()); + * } + * + * Reference(s): + * - https://github.com/google/libphonenumber + * + * @generated from message google.type.PhoneNumber + */ +export type PhoneNumber = Message<"google.type.PhoneNumber"> & { + /** + * Required. Either a regular number, or a short code. New fields may be + * added to the oneof below in the future, so clients should ignore phone + * numbers for which none of the fields they coded against are set. + * + * @generated from oneof google.type.PhoneNumber.kind + */ + kind: { + /** + * The phone number, represented as a leading plus sign ('+'), followed by a + * phone number that uses a relaxed ITU E.164 format consisting of the + * country calling code (1 to 3 digits) and the subscriber number, with no + * additional spaces or formatting, e.g.: + * - correct: "+15552220123" + * - incorrect: "+1 (555) 222-01234 x123". + * + * The ITU E.164 format limits the latter to 12 digits, but in practice not + * all countries respect that, so we relax that restriction here. + * National-only numbers are not allowed. + * + * References: + * - https://www.itu.int/rec/T-REC-E.164-201011-I + * - https://en.wikipedia.org/wiki/E.164. + * - https://en.wikipedia.org/wiki/List_of_country_calling_codes + * + * @generated from field: string e164_number = 1; + */ + value: string; + case: "e164Number"; + } | { + /** + * A short code. + * + * Reference(s): + * - https://en.wikipedia.org/wiki/Short_code + * + * @generated from field: google.type.PhoneNumber.ShortCode short_code = 2; + */ + value: PhoneNumber_ShortCode; + case: "shortCode"; + } | { case: undefined; value?: undefined }; + + /** + * The phone number's extension. The extension is not standardized in ITU + * recommendations, except for being defined as a series of numbers with a + * maximum length of 40 digits. Other than digits, some other dialing + * characters such as ',' (indicating a wait) or '#' may be stored here. + * + * Note that no regions currently use extensions with short codes, so this + * field is normally only set in conjunction with an E.164 number. It is held + * separately from the E.164 number to allow for short code extensions in the + * future. + * + * @generated from field: string extension = 3; + */ + extension: string; +}; + +/** + * Describes the message google.type.PhoneNumber. + * Use `create(PhoneNumberSchema)` to create a new message. + */ +export const PhoneNumberSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_type_phone_number, 0); + +/** + * An object representing a short code, which is a phone number that is + * typically much shorter than regular phone numbers and can be used to + * address messages in MMS and SMS systems, as well as for abbreviated dialing + * (e.g. "Text 611 to see how many minutes you have remaining on your plan."). + * + * Short codes are restricted to a region and are not internationally + * dialable, which means the same short code can exist in different regions, + * with different usage and pricing, even if those regions share the same + * country calling code (e.g. US and CA). + * + * @generated from message google.type.PhoneNumber.ShortCode + */ +export type PhoneNumber_ShortCode = Message<"google.type.PhoneNumber.ShortCode"> & { + /** + * Required. The BCP-47 region code of the location where calls to this + * short code can be made, such as "US" and "BB". + * + * Reference(s): + * - http://www.unicode.org/reports/tr35/#unicode_region_subtag + * + * @generated from field: string region_code = 1; + */ + regionCode: string; + + /** + * Required. The short code digits, without a leading plus ('+') or country + * calling code, e.g. "611". + * + * @generated from field: string number = 2; + */ + number: string; +}; + +/** + * Describes the message google.type.PhoneNumber.ShortCode. + * Use `create(PhoneNumber_ShortCodeSchema)` to create a new message. + */ +export const PhoneNumber_ShortCodeSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_type_phone_number, 0, 0); + diff --git a/schemaregistry/google/type/postal_address_pb.ts b/schemaregistry/google/type/postal_address_pb.ts new file mode 100644 index 00000000..2bde15eb --- /dev/null +++ b/schemaregistry/google/type/postal_address_pb.ts @@ -0,0 +1,193 @@ +// Copyright 2021-2024 Buf Technologies, Inc. +// +// 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.0.0 with parameter "target=ts" +// @generated from file google/type/postal_address.proto (package google.type, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/type/postal_address.proto. + */ +export const file_google_type_postal_address: GenFile = /*@__PURE__*/ + fileDesc("CiBnb29nbGUvdHlwZS9wb3N0YWxfYWRkcmVzcy5wcm90bxILZ29vZ2xlLnR5cGUi/QEKDVBvc3RhbEFkZHJlc3MSEAoIcmV2aXNpb24YASABKAUSEwoLcmVnaW9uX2NvZGUYAiABKAkSFQoNbGFuZ3VhZ2VfY29kZRgDIAEoCRITCgtwb3N0YWxfY29kZRgEIAEoCRIUCgxzb3J0aW5nX2NvZGUYBSABKAkSGwoTYWRtaW5pc3RyYXRpdmVfYXJlYRgGIAEoCRIQCghsb2NhbGl0eRgHIAEoCRITCgtzdWJsb2NhbGl0eRgIIAEoCRIVCg1hZGRyZXNzX2xpbmVzGAkgAygJEhIKCnJlY2lwaWVudHMYCiADKAkSFAoMb3JnYW5pemF0aW9uGAsgASgJQngKD2NvbS5nb29nbGUudHlwZUISUG9zdGFsQWRkcmVzc1Byb3RvUAFaRmdvb2dsZS5nb2xhbmcub3JnL2dlbnByb3RvL2dvb2dsZWFwaXMvdHlwZS9wb3N0YWxhZGRyZXNzO3Bvc3RhbGFkZHJlc3P4AQGiAgNHVFBiBnByb3RvMw"); + +/** + * Represents a postal address, e.g. for postal delivery or payments addresses. + * Given a postal address, a postal service can deliver items to a premise, P.O. + * Box or similar. + * It is not intended to model geographical locations (roads, towns, + * mountains). + * + * In typical usage an address would be created via user input or from importing + * existing data, depending on the type of process. + * + * Advice on address input / editing: + * - Use an i18n-ready address widget such as + * https://github.com/google/libaddressinput) + * - Users should not be presented with UI elements for input or editing of + * fields outside countries where that field is used. + * + * For more guidance on how to use this schema, please see: + * https://support.google.com/business/answer/6397478 + * + * @generated from message google.type.PostalAddress + */ +export type PostalAddress = Message<"google.type.PostalAddress"> & { + /** + * The schema revision of the `PostalAddress`. This must be set to 0, which is + * the latest revision. + * + * All new revisions **must** be backward compatible with old revisions. + * + * @generated from field: int32 revision = 1; + */ + revision: number; + + /** + * Required. CLDR region code of the country/region of the address. This + * is never inferred and it is up to the user to ensure the value is + * correct. See http://cldr.unicode.org/ and + * http://www.unicode.org/cldr/charts/30/supplemental/territory_information.html + * for details. Example: "CH" for Switzerland. + * + * @generated from field: string region_code = 2; + */ + regionCode: string; + + /** + * Optional. BCP-47 language code of the contents of this address (if + * known). This is often the UI language of the input form or is expected + * to match one of the languages used in the address' country/region, or their + * transliterated equivalents. + * This can affect formatting in certain countries, but is not critical + * to the correctness of the data and will never affect any validation or + * other non-formatting related operations. + * + * If this value is not known, it should be omitted (rather than specifying a + * possibly incorrect default). + * + * Examples: "zh-Hant", "ja", "ja-Latn", "en". + * + * @generated from field: string language_code = 3; + */ + languageCode: string; + + /** + * Optional. Postal code of the address. Not all countries use or require + * postal codes to be present, but where they are used, they may trigger + * additional validation with other parts of the address (e.g. state/zip + * validation in the U.S.A.). + * + * @generated from field: string postal_code = 4; + */ + postalCode: string; + + /** + * Optional. Additional, country-specific, sorting code. This is not used + * in most regions. Where it is used, the value is either a string like + * "CEDEX", optionally followed by a number (e.g. "CEDEX 7"), or just a number + * alone, representing the "sector code" (Jamaica), "delivery area indicator" + * (Malawi) or "post office indicator" (e.g. Côte d'Ivoire). + * + * @generated from field: string sorting_code = 5; + */ + sortingCode: string; + + /** + * Optional. Highest administrative subdivision which is used for postal + * addresses of a country or region. + * For example, this can be a state, a province, an oblast, or a prefecture. + * Specifically, for Spain this is the province and not the autonomous + * community (e.g. "Barcelona" and not "Catalonia"). + * Many countries don't use an administrative area in postal addresses. E.g. + * in Switzerland this should be left unpopulated. + * + * @generated from field: string administrative_area = 6; + */ + administrativeArea: string; + + /** + * Optional. Generally refers to the city/town portion of the address. + * Examples: US city, IT comune, UK post town. + * In regions of the world where localities are not well defined or do not fit + * into this structure well, leave locality empty and use address_lines. + * + * @generated from field: string locality = 7; + */ + locality: string; + + /** + * Optional. Sublocality of the address. + * For example, this can be neighborhoods, boroughs, districts. + * + * @generated from field: string sublocality = 8; + */ + sublocality: string; + + /** + * Unstructured address lines describing the lower levels of an address. + * + * Because values in address_lines do not have type information and may + * sometimes contain multiple values in a single field (e.g. + * "Austin, TX"), it is important that the line order is clear. The order of + * address lines should be "envelope order" for the country/region of the + * address. In places where this can vary (e.g. Japan), address_language is + * used to make it explicit (e.g. "ja" for large-to-small ordering and + * "ja-Latn" or "en" for small-to-large). This way, the most specific line of + * an address can be selected based on the language. + * + * The minimum permitted structural representation of an address consists + * of a region_code with all remaining information placed in the + * address_lines. It would be possible to format such an address very + * approximately without geocoding, but no semantic reasoning could be + * made about any of the address components until it was at least + * partially resolved. + * + * Creating an address only containing a region_code and address_lines, and + * then geocoding is the recommended way to handle completely unstructured + * addresses (as opposed to guessing which parts of the address should be + * localities or administrative areas). + * + * @generated from field: repeated string address_lines = 9; + */ + addressLines: string[]; + + /** + * Optional. The recipient at the address. + * This field may, under certain circumstances, contain multiline information. + * For example, it might contain "care of" information. + * + * @generated from field: repeated string recipients = 10; + */ + recipients: string[]; + + /** + * Optional. The name of the organization at the address. + * + * @generated from field: string organization = 11; + */ + organization: string; +}; + +/** + * Describes the message google.type.PostalAddress. + * Use `create(PostalAddressSchema)` to create a new message. + */ +export const PostalAddressSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_type_postal_address, 0); + diff --git a/schemaregistry/google/type/quaternion_pb.ts b/schemaregistry/google/type/quaternion_pb.ts new file mode 100644 index 00000000..b0047bef --- /dev/null +++ b/schemaregistry/google/type/quaternion_pb.ts @@ -0,0 +1,125 @@ +// Copyright 2021-2024 Buf Technologies, Inc. +// +// 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.0.0 with parameter "target=ts" +// @generated from file google/type/quaternion.proto (package google.type, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/type/quaternion.proto. + */ +export const file_google_type_quaternion: GenFile = /*@__PURE__*/ + fileDesc("Chxnb29nbGUvdHlwZS9xdWF0ZXJuaW9uLnByb3RvEgtnb29nbGUudHlwZSI4CgpRdWF0ZXJuaW9uEgkKAXgYASABKAESCQoBeRgCIAEoARIJCgF6GAMgASgBEgkKAXcYBCABKAFCbwoPY29tLmdvb2dsZS50eXBlQg9RdWF0ZXJuaW9uUHJvdG9QAVpAZ29vZ2xlLmdvbGFuZy5vcmcvZ2VucHJvdG8vZ29vZ2xlYXBpcy90eXBlL3F1YXRlcm5pb247cXVhdGVybmlvbvgBAaICA0dUUGIGcHJvdG8z"); + +/** + * A quaternion is defined as the quotient of two directed lines in a + * three-dimensional space or equivalently as the quotient of two Euclidean + * vectors (https://en.wikipedia.org/wiki/Quaternion). + * + * Quaternions are often used in calculations involving three-dimensional + * rotations (https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation), + * as they provide greater mathematical robustness by avoiding the gimbal lock + * problems that can be encountered when using Euler angles + * (https://en.wikipedia.org/wiki/Gimbal_lock). + * + * Quaternions are generally represented in this form: + * + * w + xi + yj + zk + * + * where x, y, z, and w are real numbers, and i, j, and k are three imaginary + * numbers. + * + * Our naming choice `(x, y, z, w)` comes from the desire to avoid confusion for + * those interested in the geometric properties of the quaternion in the 3D + * Cartesian space. Other texts often use alternative names or subscripts, such + * as `(a, b, c, d)`, `(1, i, j, k)`, or `(0, 1, 2, 3)`, which are perhaps + * better suited for mathematical interpretations. + * + * To avoid any confusion, as well as to maintain compatibility with a large + * number of software libraries, the quaternions represented using the protocol + * buffer below *must* follow the Hamilton convention, which defines `ij = k` + * (i.e. a right-handed algebra), and therefore: + * + * i^2 = j^2 = k^2 = ijk = −1 + * ij = −ji = k + * jk = −kj = i + * ki = −ik = j + * + * Please DO NOT use this to represent quaternions that follow the JPL + * convention, or any of the other quaternion flavors out there. + * + * Definitions: + * + * - Quaternion norm (or magnitude): `sqrt(x^2 + y^2 + z^2 + w^2)`. + * - Unit (or normalized) quaternion: a quaternion whose norm is 1. + * - Pure quaternion: a quaternion whose scalar component (`w`) is 0. + * - Rotation quaternion: a unit quaternion used to represent rotation. + * - Orientation quaternion: a unit quaternion used to represent orientation. + * + * A quaternion can be normalized by dividing it by its norm. The resulting + * quaternion maintains the same direction, but has a norm of 1, i.e. it moves + * on the unit sphere. This is generally necessary for rotation and orientation + * quaternions, to avoid rounding errors: + * https://en.wikipedia.org/wiki/Rotation_formalisms_in_three_dimensions + * + * Note that `(x, y, z, w)` and `(-x, -y, -z, -w)` represent the same rotation, + * but normalization would be even more useful, e.g. for comparison purposes, if + * it would produce a unique representation. It is thus recommended that `w` be + * kept positive, which can be achieved by changing all the signs when `w` is + * negative. + * + * + * @generated from message google.type.Quaternion + */ +export type Quaternion = Message<"google.type.Quaternion"> & { + /** + * The x component. + * + * @generated from field: double x = 1; + */ + x: number; + + /** + * The y component. + * + * @generated from field: double y = 2; + */ + y: number; + + /** + * The z component. + * + * @generated from field: double z = 3; + */ + z: number; + + /** + * The scalar component. + * + * @generated from field: double w = 4; + */ + w: number; +}; + +/** + * Describes the message google.type.Quaternion. + * Use `create(QuaternionSchema)` to create a new message. + */ +export const QuaternionSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_type_quaternion, 0); + diff --git a/schemaregistry/google/type/timeofday_pb.ts b/schemaregistry/google/type/timeofday_pb.ts new file mode 100644 index 00000000..ddcca796 --- /dev/null +++ b/schemaregistry/google/type/timeofday_pb.ts @@ -0,0 +1,75 @@ +// Copyright 2021-2024 Buf Technologies, Inc. +// +// 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.0.0 with parameter "target=ts" +// @generated from file google/type/timeofday.proto (package google.type, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file google/type/timeofday.proto. + */ +export const file_google_type_timeofday: GenFile = /*@__PURE__*/ + fileDesc("Chtnb29nbGUvdHlwZS90aW1lb2ZkYXkucHJvdG8SC2dvb2dsZS50eXBlIksKCVRpbWVPZkRheRINCgVob3VycxgBIAEoBRIPCgdtaW51dGVzGAIgASgFEg8KB3NlY29uZHMYAyABKAUSDQoFbmFub3MYBCABKAVCbAoPY29tLmdvb2dsZS50eXBlQg5UaW1lT2ZEYXlQcm90b1ABWj5nb29nbGUuZ29sYW5nLm9yZy9nZW5wcm90by9nb29nbGVhcGlzL3R5cGUvdGltZW9mZGF5O3RpbWVvZmRhefgBAaICA0dUUGIGcHJvdG8z"); + +/** + * Represents a time of day. The date and time zone are either not significant + * or are specified elsewhere. An API may choose to allow leap seconds. Related + * types are [google.type.Date][google.type.Date] and + * `google.protobuf.Timestamp`. + * + * @generated from message google.type.TimeOfDay + */ +export type TimeOfDay = Message<"google.type.TimeOfDay"> & { + /** + * Hours of day in 24 hour format. Should be from 0 to 23. An API may choose + * to allow the value "24:00:00" for scenarios like business closing time. + * + * @generated from field: int32 hours = 1; + */ + hours: number; + + /** + * Minutes of hour of day. Must be from 0 to 59. + * + * @generated from field: int32 minutes = 2; + */ + minutes: number; + + /** + * Seconds of minutes of the time. Must normally be from 0 to 59. An API may + * allow the value 60 if it allows leap-seconds. + * + * @generated from field: int32 seconds = 3; + */ + seconds: number; + + /** + * Fractions of seconds in nanoseconds. Must be from 0 to 999,999,999. + * + * @generated from field: int32 nanos = 4; + */ + nanos: number; +}; + +/** + * Describes the message google.type.TimeOfDay. + * Use `create(TimeOfDaySchema)` to create a new message. + */ +export const TimeOfDaySchema: GenMessage = /*@__PURE__*/ + messageDesc(file_google_type_timeofday, 0); + diff --git a/schemaregistry/mock-schemaregistry-client.ts b/schemaregistry/mock-schemaregistry-client.ts index 4c181af5..c2d754f5 100644 --- a/schemaregistry/mock-schemaregistry-client.ts +++ b/schemaregistry/mock-schemaregistry-client.ts @@ -124,7 +124,7 @@ class MockClient implements Client { this.schemaToVersionCache.set(cacheKey, { version: newVersion, softDeleted: false }); } - async getBySubjectAndId(subject: string, id: number): Promise { + async getBySubjectAndId(subject: string, id: number, format?: string): Promise { const cacheKey = stringify({ subject, id }); const cacheEntry = this.idToSchemaCache.get(cacheKey); @@ -143,7 +143,7 @@ class MockClient implements Client { return cacheEntry.metadata.id; } - async getLatestSchemaMetadata(subject: string): Promise { + async getLatestSchemaMetadata(subject: string, format?: string): Promise { const version = await this.latestVersion(subject); if (version === -1) { throw new RestError("No versions found for subject", 404, 40400); @@ -152,11 +152,11 @@ class MockClient implements Client { return this.getSchemaMetadata(subject, version); } - async getSchemaMetadata(subject: string, version: number, deleted: boolean = false): Promise { + async getSchemaMetadata(subject: string, version: number, deleted: boolean = false, format?: string): Promise { let json; for (const [key, value] of this.schemaToVersionCache.entries()) { const parsedKey = JSON.parse(key); - if (parsedKey.subject === subject && value.version === version && value.softDeleted === deleted) { + if (parsedKey.subject === subject && value.version === version) { json = parsedKey; } } @@ -185,7 +185,8 @@ class MockClient implements Client { }; } - async getLatestWithMetadata(subject: string, metadata: { [key: string]: string }, deleted: boolean = false): Promise { + async getLatestWithMetadata(subject: string, metadata: { [key: string]: string }, + deleted: boolean = false, format?: string): Promise { let metadataStr = ''; for (const key in metadata) { diff --git a/schemaregistry/schemaregistry-client.ts b/schemaregistry/schemaregistry-client.ts index 7e1a3241..89d64b39 100644 --- a/schemaregistry/schemaregistry-client.ts +++ b/schemaregistry/schemaregistry-client.ts @@ -114,11 +114,12 @@ export interface Client { config(): ClientConfig; register(subject: string, schema: SchemaInfo, normalize: boolean): Promise; registerFullResponse(subject: string, schema: SchemaInfo, normalize: boolean): Promise; - getBySubjectAndId(subject: string, id: number): Promise; + getBySubjectAndId(subject: string, id: number, format?: string): Promise; getId(subject: string, schema: SchemaInfo, normalize: boolean): Promise; - getLatestSchemaMetadata(subject: string): Promise; - getSchemaMetadata(subject: string, version: number, deleted: boolean): Promise; - getLatestWithMetadata(subject: string, metadata: { [key: string]: string }, deleted: boolean): Promise; + getLatestSchemaMetadata(subject: string, format?: string): Promise; + getSchemaMetadata(subject: string, version: number, deleted: boolean, format?: string): Promise; + getLatestWithMetadata(subject: string, metadata: { [key: string]: string }, + deleted: boolean, format?: string): Promise; getAllVersions(subject: string): Promise; getVersion(subject: string, schema: SchemaInfo, normalize: boolean): Promise; getAllSubjects(): Promise; @@ -221,7 +222,7 @@ export class SchemaRegistryClient implements Client { }); } - async getBySubjectAndId(subject: string, id: number): Promise { + async getBySubjectAndId(subject: string, id: number, format?: string): Promise { const cacheKey = stringify({ subject, id }); return await this.idToSchemaInfoMutex.runExclusive(async () => { const cachedSchema: SchemaInfo | undefined = this.idToSchemaInfoCache.get(cacheKey); @@ -231,8 +232,10 @@ export class SchemaRegistryClient implements Client { subject = encodeURIComponent(subject); + let formatStr = format != null ? `&format=${format}` : ''; + const response: AxiosResponse = await this.restService.handleRequest( - `/schemas/ids/${id}?subject=${subject}`, + `/schemas/ids/${id}?subject=${subject}${formatStr}`, 'GET' ); this.idToSchemaInfoCache.set(cacheKey, response.data); @@ -261,7 +264,7 @@ export class SchemaRegistryClient implements Client { }); } - async getLatestSchemaMetadata(subject: string): Promise { + async getLatestSchemaMetadata(subject: string, format?: string): Promise { return await this.latestToSchemaMutex.runExclusive(async () => { const cachedSchema: SchemaMetadata | undefined = this.latestToSchemaCache.get(subject); if (cachedSchema) { @@ -270,8 +273,10 @@ export class SchemaRegistryClient implements Client { subject = encodeURIComponent(subject); + let formatStr = format != null ? `?format=${format}` : ''; + const response: AxiosResponse = await this.restService.handleRequest( - `/subjects/${subject}/versions/latest`, + `/subjects/${subject}/versions/latest${formatStr}`, 'GET' ); this.latestToSchemaCache.set(subject, response.data); @@ -279,7 +284,7 @@ export class SchemaRegistryClient implements Client { }); } - async getSchemaMetadata(subject: string, version: number, deleted: boolean = false): Promise { + async getSchemaMetadata(subject: string, version: number, deleted: boolean = false, format?: string): Promise { const cacheKey = stringify({ subject, version, deleted }); return await this.versionToSchemaMutex.runExclusive(async () => { @@ -290,8 +295,10 @@ export class SchemaRegistryClient implements Client { subject = encodeURIComponent(subject); + let formatStr = format != null ? `&format=${format}` : ''; + const response: AxiosResponse = await this.restService.handleRequest( - `/subjects/${subject}/versions/${version}?deleted=${deleted}`, + `/subjects/${subject}/versions/${version}?deleted=${deleted}${formatStr}`, 'GET' ); this.versionToSchemaCache.set(cacheKey, response.data); @@ -299,7 +306,8 @@ export class SchemaRegistryClient implements Client { }); } - async getLatestWithMetadata(subject: string, metadata: { [key: string]: string }, deleted: boolean = false): Promise { + async getLatestWithMetadata(subject: string, metadata: { [key: string]: string }, + deleted: boolean = false, format?: string): Promise { const cacheKey = stringify({ subject, metadata, deleted }); return await this.metadataToSchemaMutex.runExclusive(async () => { @@ -318,8 +326,10 @@ export class SchemaRegistryClient implements Client { metadataStr += `&key=${encodedKey}&value=${encodedValue}`; } + let formatStr = format != null ? `&format=${format}` : ''; + const response: AxiosResponse = await this.restService.handleRequest( - `/subjects/${subject}/metadata?deleted=${deleted}&${metadataStr}`, + `/subjects/${subject}/metadata?deleted=${deleted}&${metadataStr}${formatStr}`, 'GET' ); this.metadataToSchemaCache.set(cacheKey, response.data); diff --git a/schemaregistry/serde/avro.ts b/schemaregistry/serde/avro.ts index f908c74f..7249add2 100644 --- a/schemaregistry/serde/avro.ts +++ b/schemaregistry/serde/avro.ts @@ -10,7 +10,7 @@ import { Client, RuleMode, SchemaInfo } from "../schemaregistry-client"; -import avro, { ForSchemaOptions, Type, types } from "avsc"; +import avro, {ForSchemaOptions, Type, types} from "avsc"; import UnwrappedUnionType = types.UnwrappedUnionType import WrappedUnionType = types.WrappedUnionType import ArrayType = types.ArrayType @@ -53,7 +53,31 @@ export class AvroSerializer extends Serializer implements AvroSerde { throw new Error('message is empty') } - let avroSchema = Type.forValue(msg) + let enumIndex = 1 + let fixedIndex = 1 + let recordIndex = 1 + + const namingHook: TypeHook = ( + avroSchema: avro.Schema, + opts: ForSchemaOptions, + ) => { + let schema = avroSchema as any + switch (schema.type) { + case 'enum': + schema.name = `Enum${enumIndex++}`; + break; + case 'fixed': + schema.name = `Fixed${fixedIndex++}`; + break; + case 'record': + schema.name = `Record${recordIndex++}`; + break; + default: + } + return undefined + } + + let avroSchema = Type.forValue(msg, { typeHook: namingHook }) const schema: SchemaInfo = { schemaType: 'AVRO', schema: JSON.stringify(avroSchema), @@ -175,8 +199,10 @@ async function toType( schema: avro.Schema, opts: ForSchemaOptions, ) => { - deps.forEach((_name, schema) => { - avro.Type.forSchema(JSON.parse(schema), opts) + const avroOpts = opts as AvroSerdeConfig + deps.forEach((schema, _name) => { + avroOpts.typeHook = userHook + avro.Type.forSchema(JSON.parse(schema), avroOpts) }) if (userHook) { return userHook(schema, opts) @@ -384,3 +410,5 @@ function impliedNamespace(name: string): string | null { const match = /^(.*)\.[^.]+$/.exec(name) return match ? match[1] : null } + + diff --git a/schemaregistry/serde/json.ts b/schemaregistry/serde/json.ts index b2dc4015..a0d98054 100644 --- a/schemaregistry/serde/json.ts +++ b/schemaregistry/serde/json.ts @@ -213,7 +213,7 @@ async function toValidateFunction( const spec = json.$schema if (spec === 'http://json-schema.org/draft/2020-12/schema') { const ajv2020 = new Ajv2020(conf as JsonSerdeConfig) - deps.forEach((name, schema) => { + deps.forEach((schema, name) => { ajv2020.addSchema(JSON.parse(schema), name) }) fn = ajv2020.compile(json) @@ -221,7 +221,7 @@ async function toValidateFunction( const ajv = new Ajv2019(conf as JsonSerdeConfig) ajv.addMetaSchema(draft6MetaSchema) ajv.addMetaSchema(draft7MetaSchema) - deps.forEach((name, schema) => { + deps.forEach((schema, name) => { ajv.addSchema(JSON.parse(schema), name) }) fn = ajv.compile(json) diff --git a/schemaregistry/serde/protobuf.ts b/schemaregistry/serde/protobuf.ts index bdd49568..754e0625 100644 --- a/schemaregistry/serde/protobuf.ts +++ b/schemaregistry/serde/protobuf.ts @@ -14,40 +14,92 @@ import { SchemaMetadata } from "../schemaregistry-client"; import { - createFileRegistry, + createFileRegistry, createMutableRegistry, DescField, DescFile, DescMessage, FileRegistry, - fromBinary, getExtension, hasExtension, - Registry, + fromBinary, getExtension, hasExtension, MutableRegistry, ScalarType, - toBinary + toBinary, } from "@bufbuild/protobuf"; -import { FileDescriptorProtoSchema } from "@bufbuild/protobuf/wkt"; +import { + file_google_protobuf_any, + file_google_protobuf_api, + file_google_protobuf_descriptor, + file_google_protobuf_duration, + file_google_protobuf_empty, + file_google_protobuf_field_mask, + file_google_protobuf_source_context, + file_google_protobuf_struct, + file_google_protobuf_timestamp, file_google_protobuf_type, file_google_protobuf_wrappers, + FileDescriptorProtoSchema +} from "@bufbuild/protobuf/wkt"; import { BufferWrapper, MAX_VARINT_LEN_64 } from "./buffer-wrapper"; import { LRUCache } from "lru-cache"; -import {field_meta, Meta} from "../confluent/meta_pb"; +import {field_meta, file_confluent_meta, Meta} from "../confluent/meta_pb"; import {getRuleExecutors} from "./rule-registry"; import stringify from "json-stringify-deterministic"; +import {file_confluent_types_decimal} from "../confluent/types/decimal_pb"; +import {file_google_type_calendar_period} from "../google/type/calendar_period_pb"; +import {file_google_type_color} from "../google/type/color_pb"; +import {file_google_type_date} from "../google/type/date_pb"; +import {file_google_type_datetime} from "../google/type/datetime_pb"; +import {file_google_type_dayofweek} from "../google/type/dayofweek_pb"; +import {file_google_type_fraction} from "../google/type/fraction_pb"; +import {file_google_type_expr} from "../google/type/expr_pb"; +import {file_google_type_latlng} from "../google/type/latlng_pb"; +import {file_google_type_money} from "../google/type/money_pb"; +import {file_google_type_postal_address} from "../google/type/postal_address_pb"; +import {file_google_type_quaternion} from "../google/type/quaternion_pb"; +import {file_google_type_timeofday} from "../google/type/timeofday_pb"; +import {file_google_type_month} from "../google/type/month_pb"; + +const builtinDeps = new Map([ + ['confluent/meta.proto', file_confluent_meta], + ['confluent/type/decimal.proto', file_confluent_types_decimal], + ['google/type/calendar_period.proto', file_google_type_calendar_period], + ['google/type/color.proto', file_google_type_color], + ['google/type/date.proto', file_google_type_date], + ['google/type/datetime.proto', file_google_type_datetime], + ['google/type/dayofweek.proto', file_google_type_dayofweek], + ['google/type/expr.proto', file_google_type_expr], + ['google/type/fraction.proto', file_google_type_fraction], + ['google/type/latlng.proto', file_google_type_latlng], + ['google/type/money.proto', file_google_type_money], + ['google/type/month.proto', file_google_type_month], + ['google/type/postal_address.proto', file_google_type_postal_address], + ['google/type/quaternion.proto', file_google_type_quaternion], + ['google/type/timeofday.proto', file_google_type_timeofday], + ['google/protobuf/any.proto', file_google_protobuf_any], + ['google/protobuf/api.proto', file_google_protobuf_api], + ['google/protobuf/descriptor.proto', file_google_protobuf_descriptor], + ['google/protobuf/duration.proto', file_google_protobuf_duration], + ['google/protobuf/empty.proto', file_google_protobuf_empty], + ['google/protobuf/field_mask.proto', file_google_protobuf_field_mask], + ['google/protobuf/source_context.proto', file_google_protobuf_source_context], + ['google/protobuf/struct.proto', file_google_protobuf_struct], + ['google/protobuf/timestamp.proto', file_google_protobuf_timestamp], + ['google/protobuf/type.proto', file_google_protobuf_type], + ['google/protobuf/wrappers.proto', file_google_protobuf_wrappers], +]) export interface ProtobufSerde { schemaToDescCache: LRUCache } export type ProtobufSerializerConfig = SerializerConfig & { - registry: Registry - descToSchemaCache: LRUCache + registry?: MutableRegistry } export class ProtobufSerializer extends Serializer implements ProtobufSerde { - registry: Registry + registry: MutableRegistry schemaToDescCache: LRUCache descToSchemaCache: LRUCache constructor(client: Client, serdeType: SerdeType, conf: ProtobufSerializerConfig) { super(client, serdeType, conf) - this.registry = conf.registry + this.registry = conf.registry ?? createMutableRegistry() this.schemaToDescCache = new LRUCache({ max: this.config().cacheCapacity ?? 1000 } ) this.descToSchemaCache = new LRUCache({ max: this.config().cacheCapacity ?? 1000 } ) this.fieldTransformer = async (ctx: RuleContext, fieldTransform: FieldTransform, msg: any) => { @@ -76,7 +128,7 @@ export class ProtobufSerializer extends Serializer implements ProtobufSerde { } const fileDesc = messageDesc.file const schema = await this.getSchemaInfo(fileDesc) - const [id, info] = await this.getId(topic, msg, schema) + const [id, info] = await this.getId(topic, msg, schema, 'serialized') const subject = this.subjectName(topic, info) msg = await this.executeRules(subject, topic, RuleMode.WRITE, null, info, msg, null) const msgIndexBytes = this.toMessageIndexBytes(messageDesc) @@ -114,7 +166,7 @@ export class ProtobufSerializer extends Serializer implements ProtobufSerde { toDependencies(fileDesc: DescFile, deps: Map) { deps.set(fileDesc.name, Buffer.from(toBinary(FileDescriptorProtoSchema, fileDesc.proto)).toString('base64')) fileDesc.dependencies.forEach((dep) => { - if (!this.ignoreFile(dep.name)) { + if (!isBuiltin(dep.name)) { this.toDependencies(dep, deps) } }) @@ -123,17 +175,17 @@ export class ProtobufSerializer extends Serializer implements ProtobufSerde { async resolveDependencies(fileDesc: DescFile, deps: Map, subject: string, autoRegister: boolean, normalize: boolean): Promise { const refs: Reference[] = [] - refs.length = fileDesc.dependencies.length for (let i = 0; i < fileDesc.dependencies.length; i++) { const dep = fileDesc.dependencies[i] - if (this.ignoreFile(dep.name)) { + const depName = dep.name + '.proto' + if (isBuiltin(depName)) { continue } - const ref = await this.resolveDependencies(dep, deps, dep.name, autoRegister, normalize) + const ref = await this.resolveDependencies(dep, deps, depName, autoRegister, normalize) if (ref == null) { throw new SerializationError('dependency not found') } - refs.push({name: dep.name, subject: ref.subject!, version: ref.version!}) + refs.push({name: depName, subject: ref.subject!, version: ref.version!}) } const info: SchemaInfo = { schema: deps.get(fileDesc.name)!, @@ -182,8 +234,7 @@ export class ProtobufSerializer extends Serializer implements ProtobufSerde { // done. Allocate an array large enough to hold count+1 entries and // populate first value with index const msgIndexes: number[] = [] - msgIndexes.length = count + 1 - msgIndexes[0] = index + msgIndexes.push(index) return msgIndexes } else { const msgIndexes = this.toMessageIndexes(parent, count + 1) @@ -211,12 +262,6 @@ export class ProtobufSerializer extends Serializer implements ProtobufSerde { throw new SerializationError('message descriptor not found in file descriptor'); } - ignoreFile(name: string): boolean { - return name.startsWith('confluent/') || - name.startsWith('google/protobuf/') || - name.startsWith('google/type/') - } - async fieldTransform(ctx: RuleContext, fieldTransform: FieldTransform, msg: any): Promise { const typeName = msg.$typeName if (typeName == null) { @@ -256,13 +301,13 @@ export class ProtobufDeserializer extends Deserializer implements ProtobufSerde return null } - const info = await this.getSchema(topic, payload) + const info = await this.getSchema(topic, payload, 'serialized') const fd = await this.toFileDesc(this.client, info) const [bytesRead, msgIndexes] = this.readMessageIndexes(payload.subarray(5)) const messageDesc = this.toMessageDesc(fd, msgIndexes) const subject = this.subjectName(topic, info) - const readerMeta = await this.getReaderSchema(subject) + const readerMeta = await this.getReaderSchema(subject, 'serialized') const msgBytes = payload.subarray(5 + bytesRead) let msg = fromBinary(messageDesc, msgBytes) @@ -306,16 +351,25 @@ export class ProtobufDeserializer extends Deserializer implements ProtobufSerde async parseFileDesc(client: Client, info: SchemaInfo): Promise { const deps = new Map() - await this.resolveReferences(client, info, deps) + await this.resolveReferences(client, info, deps, 'serialized') const fileDesc = fromBinary(FileDescriptorProtoSchema, Buffer.from(info.schema, 'base64')) const resolve = (depName: string) => { - const dep = deps.get(depName) - if (dep == null) { - throw new SerializationError('dependency not found') + if (isBuiltin(depName)) { + const dep = builtinDeps.get(depName) + if (dep == null) { + throw new SerializationError(`dependency ${depName} not found`) + } + return dep + } else { + const dep = deps.get(depName) + if (dep == null) { + throw new SerializationError(`dependency ${depName} not found`) + } + const fileDesc = fromBinary(FileDescriptorProtoSchema, Buffer.from(dep, 'base64')) + fileDesc.name = depName + return fileDesc } - return fromBinary(FileDescriptorProtoSchema, Buffer.from(dep, 'base64')) } - // TODO check google protos already in registry const fileRegistry = createFileRegistry(fileDesc, resolve) this.registry = createFileRegistry(this.registry, fileRegistry) return this.registry.getFile(fileDesc.name) @@ -325,9 +379,8 @@ export class ProtobufDeserializer extends Deserializer implements ProtobufSerde const bw = new BufferWrapper(payload) const count = bw.readVarInt() const msgIndexes = [] - msgIndexes.length = count for (let i = 0; i < count; i++) { - msgIndexes[i] = bw.readVarInt() + msgIndexes.push(bw.readVarInt()) } return [bw.pos, msgIndexes] } @@ -461,5 +514,8 @@ function disjoint(tags1: Set, tags2: Set): boolean { return true } - - +function isBuiltin(name: string): boolean { + return name.startsWith('confluent/') || + name.startsWith('google/protobuf/') || + name.startsWith('google/type/') +} diff --git a/schemaregistry/serde/serde.ts b/schemaregistry/serde/serde.ts index 66fc92bd..b9fb283c 100644 --- a/schemaregistry/serde/serde.ts +++ b/schemaregistry/serde/serde.ts @@ -64,22 +64,15 @@ export abstract class Serde { return strategy(topic, this.serdeType, info) } - async resolveReferences(client: Client, schema: SchemaInfo, deps: Map): Promise { + async resolveReferences(client: Client, schema: SchemaInfo, deps: Map, format?: string): Promise { let references = schema.references if (references == null) { return } for (let ref of references) { - let metadata = await client.getSchemaMetadata(ref.subject, ref.version, true) - let info = { - schema: schema.schema, - schemaType: schema.schemaType, - references: schema.references, - metadata: schema.metadata, - ruleSet: schema.ruleSet, - } + let metadata = await client.getSchemaMetadata(ref.subject, ref.version, true, format) deps.set(ref.name, metadata.schema) - await this.resolveReferences(client, info, deps) + await this.resolveReferences(client, metadata, deps) } } @@ -233,7 +226,7 @@ export abstract class Serializer extends Serde { abstract serialize(topic: string, msg: any): Promise // GetID returns a schema ID for the given schema - async getId(topic: string, msg: any, info: SchemaInfo): Promise<[number, SchemaInfo]> { + async getId(topic: string, msg: any, info: SchemaInfo, format?: string): Promise<[number, SchemaInfo]> { let autoRegister = this.config().autoRegisterSchemas let useSchemaId = this.config().useSchemaId let useLatestWithMetadata = this.conf.useLatestWithMetadata @@ -245,16 +238,16 @@ export abstract class Serializer extends Serde { if (autoRegister) { id = await this.client.register(subject, info, Boolean(normalizeSchema)) } else if (useSchemaId != null && useSchemaId >= 0) { - info = await this.client.getBySubjectAndId(subject, useSchemaId) + info = await this.client.getBySubjectAndId(subject, useSchemaId, format) id = await this.client.getId(subject, info, false) if (id !== useSchemaId) { throw new SerializationError(`failed to match schema ID (${id} != ${useSchemaId})`) } } else if (useLatestWithMetadata != null && Object.keys(useLatestWithMetadata).length !== 0) { - info = await this.client.getLatestWithMetadata(subject, useLatestWithMetadata, true) + info = await this.client.getLatestWithMetadata(subject, useLatestWithMetadata, true, format) id = await this.client.getId(subject, info, false) } else if (useLatest) { - info = await this.client.getLatestSchemaMetadata(subject) + info = await this.client.getLatestSchemaMetadata(subject, format) id = await this.client.getId(subject, info, false) } else { id = await this.client.getId(subject, info, Boolean(normalizeSchema)) @@ -287,7 +280,7 @@ export abstract class Deserializer extends Serde { return this.conf as DeserializerConfig } - async getSchema(topic: string, payload: Buffer): Promise { + async getSchema(topic: string, payload: Buffer, format?: string): Promise { const magicByte = payload.subarray(0, 1) if (!magicByte.equals(MAGIC_BYTE)) { throw new SerializationError( @@ -298,17 +291,17 @@ export abstract class Deserializer extends Serde { } const id = payload.subarray(1, 5).readInt32BE(0) let subject = this.subjectName(topic) - return await this.client.getBySubjectAndId(subject, id) + return await this.client.getBySubjectAndId(subject, id, format) } - async getReaderSchema(subject: string): Promise { + async getReaderSchema(subject: string, format?: string): Promise { let useLatestWithMetadata = this.config().useLatestWithMetadata let useLatest = this.config().useLatestVersion if (useLatestWithMetadata != null && Object.keys(useLatestWithMetadata).length !== 0) { - return await this.client.getLatestWithMetadata(subject, useLatestWithMetadata, true) + return await this.client.getLatestWithMetadata(subject, useLatestWithMetadata, true, format) } if (useLatest) { - return await this.client.getLatestSchemaMetadata(subject) + return await this.client.getLatestSchemaMetadata(subject, format) } return null } @@ -346,7 +339,7 @@ export abstract class Deserializer extends Serde { } async getMigrations(subject: string, sourceInfo: SchemaInfo, - target: SchemaMetadata): Promise { + target: SchemaMetadata, format?: string): Promise { let version = await this.client.getVersion(subject, sourceInfo, false) let source: SchemaMetadata = { id: 0, @@ -372,7 +365,7 @@ export abstract class Deserializer extends Serde { return migrations } let previous: SchemaMetadata | null = null - let versions = await this.getSchemasBetween(subject, first, last) + let versions = await this.getSchemasBetween(subject, first, last, format) for (let i = 0; i < versions.length; i++) { let version = versions[i] if (i === 0) { @@ -405,7 +398,7 @@ export abstract class Deserializer extends Serde { } async getSchemasBetween(subject: string, first: SchemaMetadata, - last: SchemaMetadata): Promise { + last: SchemaMetadata, format?: string): Promise { if (last.version!-first.version! <= 1) { return [first, last] } @@ -413,7 +406,7 @@ export abstract class Deserializer extends Serde { let version2 = last.version! let result = [first] for (let i = version1 + 1; i < version2; i++) { - let meta = await this.client.getSchemaMetadata(subject, i, true) + let meta = await this.client.getSchemaMetadata(subject, i, true, format) result.push(meta) } result.push(last) diff --git a/test/schemaregistry/serde/avro.spec.ts b/test/schemaregistry/serde/avro.spec.ts index 8480d80f..a2e42475 100644 --- a/test/schemaregistry/serde/avro.spec.ts +++ b/test/schemaregistry/serde/avro.spec.ts @@ -1,4 +1,4 @@ -import {describe, expect, it} from '@jest/globals'; +import {afterEach, describe, expect, it} from '@jest/globals'; import {ClientConfig} from "../../../schemaregistry/rest-service"; import { AvroDeserializer, AvroDeserializerConfig, @@ -46,6 +46,18 @@ const demoSchema = ` ] } ` +const rootPointerSchema = ` +{ + "name": "NestedTestPointerRecord", + "type": "record", + "fields": [ + { + "name": "otherField", + "type": ["null", "DemoSchema"] + } +] +} +` const f1Schema = ` { "name": "F1Schema", @@ -63,10 +75,25 @@ const f1Schema = ` const fieldEncryptionExecutor = FieldEncryptionExecutor.register() LocalKmsDriver.register() +//const baseURL = 'http://localhost:8081' +const baseURL = 'mock://' + +const topic = 'topic1' +const subject = topic + '-value' + describe('AvroSerializer', () => { + afterEach(async () => { + let conf: ClientConfig = { + baseURLs: [baseURL], + cacheCapacity: 1000 + } + let client = SchemaRegistryClient.newClient(conf) + await client.deleteSubject(subject, false) + await client.deleteSubject(subject, true) + }) it('basic serialization', async () => { let conf: ClientConfig = { - baseURLs: ['mock://'], + baseURLs: [baseURL], cacheCapacity: 1000 } let client = SchemaRegistryClient.newClient(conf) @@ -78,19 +105,92 @@ describe('AvroSerializer', () => { boolField: true, bytesField: Buffer.from([1, 2]), } - let bytes = await ser.serialize("topic1", obj) + let bytes = await ser.serialize(topic, obj) let deser = new AvroDeserializer(client, SerdeType.VALUE, {}) - let obj2 = await deser.deserialize("topic1", bytes) + let obj2 = await deser.deserialize(topic, bytes) expect(obj2.intField).toEqual(obj.intField); expect(obj2.doubleField).toBeCloseTo(obj.doubleField, 0.001); expect(obj2.stringField).toEqual(obj.stringField); expect(obj2.boolField).toEqual(obj.boolField); expect(obj2.bytesField).toEqual(obj.bytesField); }) + it('serialize nested', async () => { + let conf: ClientConfig = { + baseURLs: [baseURL], + cacheCapacity: 1000 + } + let client = SchemaRegistryClient.newClient(conf) + let ser = new AvroSerializer(client, SerdeType.VALUE, {autoRegisterSchemas: true}) + + let nested = { + intField: 123, + doubleField: 45.67, + stringField: 'hi', + boolField: true, + bytesField: Buffer.from([1, 2]), + } + let obj = { + otherField: nested + } + let bytes = await ser.serialize(topic, obj) + + let deser = new AvroDeserializer(client, SerdeType.VALUE, {}) + let obj2 = await deser.deserialize(topic, bytes) + expect(obj2.otherField.intField).toEqual(nested.intField); + expect(obj2.otherField.doubleField).toBeCloseTo(nested.doubleField, 0.001); + expect(obj2.otherField.stringField).toEqual(nested.stringField); + expect(obj2.otherField.boolField).toEqual(nested.boolField); + expect(obj2.otherField.bytesField).toEqual(nested.bytesField); + }) + it('serialize reference', async () => { + let conf: ClientConfig = { + baseURLs: [baseURL], + cacheCapacity: 1000 + } + let client = SchemaRegistryClient.newClient(conf) + let ser = new AvroSerializer(client, SerdeType.VALUE, {useLatestVersion: true}) + + let info: SchemaInfo = { + schemaType: 'AVRO', + schema: demoSchema, + } + await client.register('demo-value', info , false) + + info = { + schemaType: 'AVRO', + schema: rootPointerSchema, + references: [{ + name: 'DemoSchema', + subject: 'demo-value', + version: 1 + }] + } + await client.register(subject, info , false) + + let nested = { + intField: 123, + doubleField: 45.67, + stringField: 'hi', + boolField: true, + bytesField: Buffer.from([1, 2]), + } + let obj = { + otherField: nested + } + let bytes = await ser.serialize(topic, obj) + + let deser = new AvroDeserializer(client, SerdeType.VALUE, {}) + let obj2 = await deser.deserialize(topic, bytes) + expect(obj2.otherField.intField).toEqual(nested.intField); + expect(obj2.otherField.doubleField).toBeCloseTo(nested.doubleField, 0.001); + expect(obj2.otherField.stringField).toEqual(nested.stringField); + expect(obj2.otherField.boolField).toEqual(nested.boolField); + expect(obj2.otherField.bytesField).toEqual(nested.bytesField); + }) it('basic encryption', async () => { let conf: ClientConfig = { - baseURLs: ['mock://'], + baseURLs: [baseURL], cacheCapacity: 1000 } let client = SchemaRegistryClient.newClient(conf) @@ -126,8 +226,7 @@ describe('AvroSerializer', () => { ruleSet } - let id = await client.register('topic1-value', info, false) - expect(id).toEqual(1) + await client.register(subject, info, false) let obj = { intField: 123, @@ -136,7 +235,7 @@ describe('AvroSerializer', () => { boolField: true, bytesField: Buffer.from([1, 2]), } - let bytes = await ser.serialize("topic1", obj) + let bytes = await ser.serialize(topic, obj) // reset encrypted field obj.stringField = 'hi' @@ -149,7 +248,7 @@ describe('AvroSerializer', () => { } let deser = new AvroDeserializer(client, SerdeType.VALUE, deserConfig) fieldEncryptionExecutor.client = dekClient - let obj2 = await deser.deserialize("topic1", bytes) + let obj2 = await deser.deserialize(topic, bytes) expect(obj2.intField).toEqual(obj.intField); expect(obj2.doubleField).toBeCloseTo(obj.doubleField, 0.001); expect(obj2.stringField).toEqual(obj.stringField); @@ -158,7 +257,7 @@ describe('AvroSerializer', () => { }) it('basic encryption with preserialized data', async () => { let conf: ClientConfig = { - baseURLs: ['mock://'], + baseURLs: [baseURL], cacheCapacity: 1000 } let client = SchemaRegistryClient.newClient(conf) @@ -186,8 +285,7 @@ describe('AvroSerializer', () => { ruleSet } - let id = await client.register('topic1-value', info, false) - expect(id).toEqual(1) + await client.register(subject, info, false) let obj = { f1: 'hello world' @@ -203,15 +301,15 @@ describe('AvroSerializer', () => { await dekClient.registerKek("kek1", "local-kms", "mykey", false) const encryptedDek = "07V2ndh02DA73p+dTybwZFm7DKQSZN1tEwQh+FoX1DZLk4Yj2LLu4omYjp/84tAg3BYlkfGSz+zZacJHIE4=" - await dekClient.registerDek("kek1", "topic1-value", "AES256_GCM", 1, encryptedDek) + await dekClient.registerDek("kek1", subject, "AES256_GCM", 1, encryptedDek) const bytes = Buffer.from([0, 0, 0, 0, 1, 104, 122, 103, 121, 47, 106, 70, 78, 77, 86, 47, 101, 70, 105, 108, 97, 72, 114, 77, 121, 101, 66, 103, 100, 97, 86, 122, 114, 82, 48, 117, 100, 71, 101, 111, 116, 87, 56, 99, 65, 47, 74, 97, 108, 55, 117, 107, 114, 43, 77, 47, 121, 122]) - let obj2 = await deser.deserialize("topic1", bytes) + let obj2 = await deser.deserialize(topic, bytes) expect(obj2.f1).toEqual(obj.f1); }) it('deterministic encryption with preserialized data', async () => { let conf: ClientConfig = { - baseURLs: ['mock://'], + baseURLs: [baseURL], cacheCapacity: 1000 } let client = SchemaRegistryClient.newClient(conf) @@ -240,8 +338,7 @@ describe('AvroSerializer', () => { ruleSet } - let id = await client.register('topic1-value', info, false) - expect(id).toEqual(1) + await client.register(subject, info, false) let obj = { f1: 'hello world' @@ -257,15 +354,15 @@ describe('AvroSerializer', () => { await dekClient.registerKek("kek1", "local-kms", "mykey", false) const encryptedDek = "YSx3DTlAHrmpoDChquJMifmPntBzxgRVdMzgYL82rgWBKn7aUSnG+WIu9ozBNS3y2vXd++mBtK07w4/W/G6w0da39X9hfOVZsGnkSvry/QRht84V8yz3dqKxGMOK5A==" - await dekClient.registerDek("kek1", "topic1-value", "AES256_SIV", 1, encryptedDek) + await dekClient.registerDek("kek1", subject, "AES256_SIV", 1, encryptedDek) const bytes = Buffer.from([0, 0, 0, 0, 1, 72, 68, 54, 89, 116, 120, 114, 108, 66, 110, 107, 84, 87, 87, 57, 78, 54, 86, 98, 107, 51, 73, 73, 110, 106, 87, 72, 56, 49, 120, 109, 89, 104, 51, 107, 52, 100]) - let obj2 = await deser.deserialize("topic1", bytes) + let obj2 = await deser.deserialize(topic, bytes) expect(obj2.f1).toEqual(obj.f1); }) it('dek rotation encryption with preserialized data', async () => { let conf: ClientConfig = { - baseURLs: ['mock://'], + baseURLs: [baseURL], cacheCapacity: 1000 } let client = SchemaRegistryClient.newClient(conf) @@ -294,8 +391,7 @@ describe('AvroSerializer', () => { ruleSet } - let id = await client.register('topic1-value', info, false) - expect(id).toEqual(1) + await client.register(subject, info, false) let obj = { f1: 'hello world' @@ -311,10 +407,10 @@ describe('AvroSerializer', () => { await dekClient.registerKek("kek1", "local-kms", "mykey", false) const encryptedDek = "W/v6hOQYq1idVAcs1pPWz9UUONMVZW4IrglTnG88TsWjeCjxmtRQ4VaNe/I5dCfm2zyY9Cu0nqdvqImtUk4=" - await dekClient.registerDek("kek1", "topic1-value", "AES256_GCM", 1, encryptedDek) + await dekClient.registerDek("kek1", subject, "AES256_GCM", 1, encryptedDek) const bytes = Buffer.from([0, 0, 0, 0, 1, 120, 65, 65, 65, 65, 65, 65, 71, 52, 72, 73, 54, 98, 49, 110, 88, 80, 88, 113, 76, 121, 71, 56, 99, 73, 73, 51, 53, 78, 72, 81, 115, 101, 113, 113, 85, 67, 100, 43, 73, 101, 76, 101, 70, 86, 65, 101, 78, 112, 83, 83, 51, 102, 120, 80, 110, 74, 51, 50, 65, 61]) - let obj2 = await deser.deserialize("topic1", bytes) + let obj2 = await deser.deserialize(topic, bytes) expect(obj2.f1).toEqual(obj.f1); }) }) diff --git a/test/schemaregistry/serde/json.spec.ts b/test/schemaregistry/serde/json.spec.ts new file mode 100644 index 00000000..c28f6f9d --- /dev/null +++ b/test/schemaregistry/serde/json.spec.ts @@ -0,0 +1,209 @@ +import {afterEach, describe, expect, it} from '@jest/globals'; +import {ClientConfig} from "../../../schemaregistry/rest-service"; +import {SerdeType} from "../../../schemaregistry/serde/serde"; +import { + Rule, + RuleMode, + RuleSet, + SchemaInfo, + SchemaRegistryClient +} from "../../../schemaregistry/schemaregistry-client"; +import {LocalKmsDriver} from "../../../schemaregistry/rules/encryption/localkms/local-driver"; +import {FieldEncryptionExecutor} from "../../../schemaregistry/rules/encryption/encrypt-executor"; +import { + JsonDeserializer, JsonDeserializerConfig, + JsonSerializer, + JsonSerializerConfig +} from "../../../schemaregistry/serde/json"; + +const fieldEncryptionExecutor = FieldEncryptionExecutor.register() +LocalKmsDriver.register() + +//const baseURL = 'http://localhost:8081' +const baseURL = 'mock://' + +const topic = 'topic1' +const subject = topic + '-value' + +const rootSchema = ` +{ + "type": "object", + "properties": { + "otherField": { "$ref": "DemoSchema" } + } +} +` + +const demoSchema = ` +{ + "type": "object", + "properties": { + "intField": { "type": "integer" }, + "doubleField": { "type": "number" }, + "stringField": { + "type": "string", + "confluent:tags": [ "PII" ] + }, + "boolField": { "type": "boolean" }, + "bytesField": { + "type": "string", + "contentEncoding": "base64", + "confluent:tags": [ "PII" ] + } + } +} +` + +describe('JsonSerializer', () => { + afterEach(async () => { + let conf: ClientConfig = { + baseURLs: [baseURL], + cacheCapacity: 1000 + } + let client = SchemaRegistryClient.newClient(conf) + await client.deleteSubject(subject, false) + await client.deleteSubject(subject, true) + }) + it('basic serialization', async () => { + let conf: ClientConfig = { + baseURLs: [baseURL], + cacheCapacity: 1000 + } + let client = SchemaRegistryClient.newClient(conf) + let ser = new JsonSerializer(client, SerdeType.VALUE, {autoRegisterSchemas: true}) + let obj = { + intField: 123, + doubleField: 45.67, + stringField: 'hi', + boolField: true, + bytesField: Buffer.from([0, 0, 0, 1]).toString('base64') + } + let bytes = await ser.serialize(topic, obj) + + let deser = new JsonDeserializer(client, SerdeType.VALUE, {}) + let obj2 = await deser.deserialize(topic, bytes) + expect(obj2).toEqual(obj) + }) + it('serialize nested', async () => { + let conf: ClientConfig = { + baseURLs: [baseURL], + cacheCapacity: 1000 + } + let client = SchemaRegistryClient.newClient(conf) + let ser = new JsonSerializer(client, SerdeType.VALUE, {autoRegisterSchemas: true}) + + let obj = { + intField: 123, + doubleField: 45.67, + stringField: 'hi', + boolField: true, + bytesField: Buffer.from([0, 0, 0, 1]).toString('base64') + } + let bytes = await ser.serialize(topic, obj) + + let deser = new JsonDeserializer(client, SerdeType.VALUE, {}) + let obj2 = await deser.deserialize(topic, bytes) + expect(obj2).toEqual(obj) + }) + it('serialize reference', async () => { + let conf: ClientConfig = { + baseURLs: [baseURL], + cacheCapacity: 1000 + } + let client = SchemaRegistryClient.newClient(conf) + let ser = new JsonSerializer(client, SerdeType.VALUE, {useLatestVersion: true}) + + let info: SchemaInfo = { + schemaType: 'JSON', + schema: demoSchema + } + await client.register('demo-value', info, false) + + info = { + schemaType: 'JSON', + schema: rootSchema, + references: [{ + name: 'DemoSchema', + subject: 'demo-value', + version: 1 + }] + } + await client.register(subject, info, false) + + let obj = { + intField: 123, + doubleField: 45.67, + stringField: 'hi', + boolField: true, + bytesField: Buffer.from([0, 0, 0, 1]).toString('base64') + } + let bytes = await ser.serialize(topic, obj) + + let deser = new JsonDeserializer(client, SerdeType.VALUE, {}) + let obj2 = await deser.deserialize(topic, bytes) + expect(obj2).toEqual(obj) + }) + it('basic encryption', async () => { + let conf: ClientConfig = { + baseURLs: [baseURL], + cacheCapacity: 1000 + } + let client = SchemaRegistryClient.newClient(conf) + let serConfig: JsonSerializerConfig = { + useLatestVersion: true, + ruleConfig: { + secret: 'mysecret' + } + } + let ser = new JsonSerializer(client, SerdeType.VALUE, serConfig) + let dekClient = fieldEncryptionExecutor.client! + + let encRule: Rule = { + name: 'test-encrypt', + kind: 'TRANSFORM', + mode: RuleMode.WRITEREAD, + type: 'ENCRYPT', + tags: ['PII'], + params: { + 'encrypt.kek.name': 'kek1', + 'encrypt.kms.type': 'local-kms', + 'encrypt.kms.key.id': 'mykey', + }, + onFailure: 'ERROR,ERROR' + } + let ruleSet: RuleSet = { + domainRules: [encRule] + } + + let info: SchemaInfo = { + schemaType: 'JSON', + schema: demoSchema, + ruleSet + } + + await client.register(subject, info, false) + + let obj = { + intField: 123, + doubleField: 45.67, + stringField: 'hi', + boolField: true, + bytesField: Buffer.from([0, 0, 0, 1]).toString('base64') + } + let bytes = await ser.serialize(topic, obj) + + // reset encrypted field + obj.stringField = 'hi' + obj.bytesField = Buffer.from([0, 0, 0, 1]).toString('base64') + + let deserConfig: JsonDeserializerConfig = { + ruleConfig: { + secret: 'mysecret' + } + } + let deser = new JsonDeserializer(client, SerdeType.VALUE, deserConfig) + fieldEncryptionExecutor.client = dekClient + let obj2 = await deser.deserialize(topic, bytes) + expect(obj2).toEqual(obj) + }) +}) diff --git a/test/schemaregistry/serde/protobuf.spec.ts b/test/schemaregistry/serde/protobuf.spec.ts new file mode 100644 index 00000000..de238e35 --- /dev/null +++ b/test/schemaregistry/serde/protobuf.spec.ts @@ -0,0 +1,205 @@ +import {afterEach, describe, expect, it} from '@jest/globals'; +import {ClientConfig} from "../../../schemaregistry/rest-service"; +import { + ProtobufDeserializer, ProtobufDeserializerConfig, + ProtobufSerializer, ProtobufSerializerConfig, +} from "../../../schemaregistry/serde/protobuf"; +import {SerdeType} from "../../../schemaregistry/serde/serde"; +import { + Rule, + RuleMode, + RuleSet, + SchemaInfo, + SchemaRegistryClient +} from "../../../schemaregistry/schemaregistry-client"; +import {LocalKmsDriver} from "../../../schemaregistry/rules/encryption/localkms/local-driver"; +import {FieldEncryptionExecutor} from "../../../schemaregistry/rules/encryption/encrypt-executor"; +import {AuthorSchema, file_test_schemaregistry_serde_example, PizzaSchema} from "./test/example_pb"; +import {create, toBinary} from "@bufbuild/protobuf"; +import {FileDescriptorProtoSchema} from "@bufbuild/protobuf/wkt"; +import { + NestedMessage_InnerMessageSchema +} from "./test/nested_pb"; +import {TestMessageSchema} from "./test/test_pb"; +import {DependencyMessageSchema} from "./test/dep_pb"; + +const fieldEncryptionExecutor = FieldEncryptionExecutor.register() +LocalKmsDriver.register() + +//const baseURL = 'http://localhost:8081' +const baseURL = 'mock://' + +const topic = 'topic1' +const subject = topic + '-value' + +describe('ProtobufSerializer', () => { + afterEach(async () => { + let conf: ClientConfig = { + baseURLs: [baseURL], + cacheCapacity: 1000 + } + let client = SchemaRegistryClient.newClient(conf) + await client.deleteSubject(subject, false) + await client.deleteSubject(subject, true) + }) + it('basic serialization', async () => { + let conf: ClientConfig = { + baseURLs: [baseURL], + cacheCapacity: 1000 + } + let client = SchemaRegistryClient.newClient(conf) + let ser = new ProtobufSerializer(client, SerdeType.VALUE, {autoRegisterSchemas: true}) + ser.registry.add(AuthorSchema) + let obj = create(AuthorSchema, { + name: 'Kafka', + id: 123, + picture: Buffer.from([1, 2]), + works: ['The Castle', 'The Trial'] + }) + let bytes = await ser.serialize(topic, obj) + + let deser = new ProtobufDeserializer(client, SerdeType.VALUE, {}) + let obj2 = await deser.deserialize(topic, bytes) + expect(obj2).toEqual(obj) + }) + it('serialize second messsage', async () => { + let conf: ClientConfig = { + baseURLs: [baseURL], + cacheCapacity: 1000 + } + let client = SchemaRegistryClient.newClient(conf) + let ser = new ProtobufSerializer(client, SerdeType.VALUE, {autoRegisterSchemas: true}) + ser.registry.add(PizzaSchema) + let obj = create(PizzaSchema, { + size: 'Extra extra large', + toppings: ['anchovies', 'mushrooms'] + }) + let bytes = await ser.serialize(topic, obj) + + let deser = new ProtobufDeserializer(client, SerdeType.VALUE, {}) + let obj2 = await deser.deserialize(topic, bytes) + expect(obj2).toEqual(obj) + }) + it('serialize nested messsage', async () => { + let conf: ClientConfig = { + baseURLs: [baseURL], + cacheCapacity: 1000 + } + let client = SchemaRegistryClient.newClient(conf) + let ser = new ProtobufSerializer(client, SerdeType.VALUE, {autoRegisterSchemas: true}) + ser.registry.add(NestedMessage_InnerMessageSchema) + let obj = create(NestedMessage_InnerMessageSchema, { + id: "inner" + }) + let bytes = await ser.serialize(topic, obj) + + let deser = new ProtobufDeserializer(client, SerdeType.VALUE, {}) + let obj2 = await deser.deserialize(topic, bytes) + expect(obj2).toEqual(obj) + }) + it('serialize reference', async () => { + let conf: ClientConfig = { + baseURLs: [baseURL], + cacheCapacity: 1000 + } + let client = SchemaRegistryClient.newClient(conf) + let ser = new ProtobufSerializer(client, SerdeType.VALUE, {autoRegisterSchemas: true}) + ser.registry.add(TestMessageSchema) + ser.registry.add(DependencyMessageSchema) + let msg = create(TestMessageSchema, { + testString: "hi", + testBool: true, + testBytes: Buffer.from([1, 2]), + testDouble: 1.23, + testFloat: 3.45, + testFixed32: 67, + testFixed64: 89n, + testInt32: 100, + testInt64: 200n, + testSfixed32: 300, + testSfixed64: 400n, + testSint32: 500, + testSint64: 600n, + testUint32: 700, + testUint64: 800n, + }) + let obj = create(DependencyMessageSchema, { + isActive: true, + testMesssage: msg + }) + let bytes = await ser.serialize(topic, obj) + + let deser = new ProtobufDeserializer(client, SerdeType.VALUE, {}) + let obj2 = await deser.deserialize(topic, bytes) + expect(obj2.testMesssage.testString).toEqual(msg.testString); + expect(obj2.testMesssage.testBool).toEqual(msg.testBool); + expect(obj2.testMesssage.testBytes).toEqual(msg.testBytes); + expect(obj2.testMesssage.testDouble).toBeCloseTo(msg.testDouble, 0.001); + expect(obj2.testMesssage.testFloat).toBeCloseTo(msg.testFloat, 0.001); + expect(obj2.testMesssage.testFixed32).toEqual(msg.testFixed32); + expect(obj2.testMesssage.testFixed64).toEqual(msg.testFixed64); + }) + it('basic encryption', async () => { + let conf: ClientConfig = { + baseURLs: [baseURL], + cacheCapacity: 1000 + } + let client = SchemaRegistryClient.newClient(conf) + let serConfig: ProtobufSerializerConfig = { + useLatestVersion: true, + ruleConfig: { + secret: 'mysecret' + } + } + let ser = new ProtobufSerializer(client, SerdeType.VALUE, serConfig) + ser.registry.add(AuthorSchema) + let dekClient = fieldEncryptionExecutor.client! + + let encRule: Rule = { + name: 'test-encrypt', + kind: 'TRANSFORM', + mode: RuleMode.WRITEREAD, + type: 'ENCRYPT', + tags: ['PII'], + params: { + 'encrypt.kek.name': 'kek1', + 'encrypt.kms.type': 'local-kms', + 'encrypt.kms.key.id': 'mykey', + }, + onFailure: 'ERROR,ERROR' + } + let ruleSet: RuleSet = { + domainRules: [encRule] + } + + let info: SchemaInfo = { + schemaType: 'PROTOBUF', + schema: Buffer.from(toBinary(FileDescriptorProtoSchema, file_test_schemaregistry_serde_example.proto)).toString('base64'), + ruleSet + } + + await client.register(subject, info, false) + + let obj = create(AuthorSchema, { + name: 'Kafka', + id: 123, + picture: Buffer.from([1, 2]), + works: ['The Castle', 'The Trial'] + }) + let bytes = await ser.serialize(topic, obj) + + // reset encrypted field + obj.name = 'Kafka' + obj.picture = Buffer.from([1, 2]) + + let deserConfig: ProtobufDeserializerConfig = { + ruleConfig: { + secret: 'mysecret' + } + } + let deser = new ProtobufDeserializer(client, SerdeType.VALUE, deserConfig) + fieldEncryptionExecutor.client = dekClient + let obj2 = await deser.deserialize(topic, bytes) + expect(obj2).toEqual(obj) + }) +}) diff --git a/test/schemaregistry/serde/test/cycle_pb.ts b/test/schemaregistry/serde/test/cycle_pb.ts new file mode 100644 index 00000000..73e60993 --- /dev/null +++ b/test/schemaregistry/serde/test/cycle_pb.ts @@ -0,0 +1,36 @@ +// @generated by protoc-gen-es v2.0.0 with parameter "target=ts" +// @generated from file test/schemaregistry/serde/cycle.proto (package test, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file test/schemaregistry/serde/cycle.proto. + */ +export const file_test_schemaregistry_serde_cycle: GenFile = /*@__PURE__*/ + fileDesc("CiV0ZXN0L3NjaGVtYXJlZ2lzdHJ5L3NlcmRlL2N5Y2xlLnByb3RvEgR0ZXN0IjsKCkxpbmtlZExpc3QSDQoFdmFsdWUYASABKAUSHgoEbmV4dBgKIAEoCzIQLnRlc3QuTGlua2VkTGlzdEIJWgcuLi90ZXN0YgZwcm90bzM"); + +/** + * @generated from message test.LinkedList + */ +export type LinkedList = Message<"test.LinkedList"> & { + /** + * @generated from field: int32 value = 1; + */ + value: number; + + /** + * @generated from field: test.LinkedList next = 10; + */ + next?: LinkedList; +}; + +/** + * Describes the message test.LinkedList. + * Use `create(LinkedListSchema)` to create a new message. + */ +export const LinkedListSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_test_schemaregistry_serde_cycle, 0); + diff --git a/test/schemaregistry/serde/test/dep_pb.ts b/test/schemaregistry/serde/test/dep_pb.ts new file mode 100644 index 00000000..80783aee --- /dev/null +++ b/test/schemaregistry/serde/test/dep_pb.ts @@ -0,0 +1,38 @@ +// @generated by protoc-gen-es v2.0.0 with parameter "target=ts" +// @generated from file test/schemaregistry/serde/dep.proto (package test, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { TestMessage } from "./test_pb"; +import { file_test_schemaregistry_serde_test } from "./test_pb"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file test/schemaregistry/serde/dep.proto. + */ +export const file_test_schemaregistry_serde_dep: GenFile = /*@__PURE__*/ + fileDesc("CiN0ZXN0L3NjaGVtYXJlZ2lzdHJ5L3NlcmRlL2RlcC5wcm90bxIEdGVzdCJQChFEZXBlbmRlbmN5TWVzc2FnZRIRCglpc19hY3RpdmUYASABKAgSKAoNdGVzdF9tZXNzc2FnZRgCIAEoCzIRLnRlc3QuVGVzdE1lc3NhZ2VCCVoHLi4vdGVzdGIGcHJvdG8z", [file_test_schemaregistry_serde_test]); + +/** + * @generated from message test.DependencyMessage + */ +export type DependencyMessage = Message<"test.DependencyMessage"> & { + /** + * @generated from field: bool is_active = 1; + */ + isActive: boolean; + + /** + * @generated from field: test.TestMessage test_messsage = 2; + */ + testMesssage?: TestMessage; +}; + +/** + * Describes the message test.DependencyMessage. + * Use `create(DependencyMessageSchema)` to create a new message. + */ +export const DependencyMessageSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_test_schemaregistry_serde_dep, 0); + diff --git a/test/schemaregistry/serde/test/example_pb.ts b/test/schemaregistry/serde/test/example_pb.ts new file mode 100644 index 00000000..2120dfd8 --- /dev/null +++ b/test/schemaregistry/serde/test/example_pb.ts @@ -0,0 +1,69 @@ +// @generated by protoc-gen-es v2.0.0 with parameter "target=ts" +// @generated from file test/schemaregistry/serde/example.proto (package test, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import { file_confluent_meta } from "../../../../schemaregistry/confluent/meta_pb"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file test/schemaregistry/serde/example.proto. + */ +export const file_test_schemaregistry_serde_example: GenFile = /*@__PURE__*/ + fileDesc("Cid0ZXN0L3NjaGVtYXJlZ2lzdHJ5L3NlcmRlL2V4YW1wbGUucHJvdG8SBHRlc3QiVgoGQXV0aG9yEhYKBG5hbWUYASABKAlCCIJEBRoDUElJEgoKAmlkGAIgASgFEhkKB3BpY3R1cmUYAyABKAxCCIJEBRoDUElJEg0KBXdvcmtzGAQgAygJIicKBVBpenphEgwKBHNpemUYASABKAkSEAoIdG9wcGluZ3MYAiADKAlCCVoHLi4vdGVzdGIGcHJvdG8z", [file_confluent_meta]); + +/** + * @generated from message test.Author + */ +export type Author = Message<"test.Author"> & { + /** + * @generated from field: string name = 1; + */ + name: string; + + /** + * @generated from field: int32 id = 2; + */ + id: number; + + /** + * @generated from field: bytes picture = 3; + */ + picture: Uint8Array; + + /** + * @generated from field: repeated string works = 4; + */ + works: string[]; +}; + +/** + * Describes the message test.Author. + * Use `create(AuthorSchema)` to create a new message. + */ +export const AuthorSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_test_schemaregistry_serde_example, 0); + +/** + * @generated from message test.Pizza + */ +export type Pizza = Message<"test.Pizza"> & { + /** + * @generated from field: string size = 1; + */ + size: string; + + /** + * @generated from field: repeated string toppings = 2; + */ + toppings: string[]; +}; + +/** + * Describes the message test.Pizza. + * Use `create(PizzaSchema)` to create a new message. + */ +export const PizzaSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_test_schemaregistry_serde_example, 1); + diff --git a/test/schemaregistry/serde/test/nested_pb.ts b/test/schemaregistry/serde/test/nested_pb.ts new file mode 100644 index 00000000..a76d1dfb --- /dev/null +++ b/test/schemaregistry/serde/test/nested_pb.ts @@ -0,0 +1,221 @@ +// @generated by protoc-gen-es v2.0.0 with parameter "target=ts" +// @generated from file test/schemaregistry/serde/nested.proto (package test, syntax proto3) +/* eslint-disable */ + +import type { GenEnum, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { enumDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { Timestamp } from "@bufbuild/protobuf/wkt"; +import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file test/schemaregistry/serde/nested.proto. + */ +export const file_test_schemaregistry_serde_nested: GenFile = /*@__PURE__*/ + fileDesc("CiZ0ZXN0L3NjaGVtYXJlZ2lzdHJ5L3NlcmRlL25lc3RlZC5wcm90bxIEdGVzdCJsCgZVc2VySWQSFwoNa2Fma2FfdXNlcl9pZBgBIAEoCUgAEhcKDW90aGVyX3VzZXJfaWQYAiABKAVIABIlCgphbm90aGVyX2lkGAMgASgLMg8udGVzdC5NZXNzYWdlSWRIAEIJCgd1c2VyX2lkIhcKCU1lc3NhZ2VJZBIKCgJpZBgBIAEoCSJSCgtDb21wbGV4VHlwZRIQCgZvbmVfaWQYASABKAlIABISCghvdGhlcl9pZBgCIAEoBUgAEhEKCWlzX2FjdGl2ZRgDIAEoCEIKCghzb21lX3ZhbCLcAwoNTmVzdGVkTWVzc2FnZRIdCgd1c2VyX2lkGAEgASgLMgwudGVzdC5Vc2VySWQSEQoJaXNfYWN0aXZlGAIgASgIEhoKEmV4cGVyaW1lbnRzX2FjdGl2ZRgDIAMoCRIuCgp1cGRhdGVkX2F0GAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIcCgZzdGF0dXMYBSABKA4yDC50ZXN0LlN0YXR1cxInCgxjb21wbGV4X3R5cGUYBiABKAsyES50ZXN0LkNvbXBsZXhUeXBlEjIKCG1hcF90eXBlGAcgAygLMiAudGVzdC5OZXN0ZWRNZXNzYWdlLk1hcFR5cGVFbnRyeRIvCgVpbm5lchgIIAEoCzIgLnRlc3QuTmVzdGVkTWVzc2FnZS5Jbm5lck1lc3NhZ2UaLgoMTWFwVHlwZUVudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEaKwoMSW5uZXJNZXNzYWdlEgoKAmlkGAEgASgJEg8KA2lkcxgCIAMoBUICEAEiKAoJSW5uZXJFbnVtEggKBFpFUk8QABINCglBTFNPX1pFUk8QABoCEAFKBAgOEA9KBAgPEBBKBAgJEAxSA2Zvb1IDYmFyKiIKBlN0YXR1cxIKCgZBQ1RJVkUQABIMCghJTkFDVElWRRABQglaBy4uL3Rlc3RiBnByb3RvMw", [file_google_protobuf_timestamp]); + +/** + * @generated from message test.UserId + */ +export type UserId = Message<"test.UserId"> & { + /** + * @generated from oneof test.UserId.user_id + */ + userId: { + /** + * @generated from field: string kafka_user_id = 1; + */ + value: string; + case: "kafkaUserId"; + } | { + /** + * @generated from field: int32 other_user_id = 2; + */ + value: number; + case: "otherUserId"; + } | { + /** + * @generated from field: test.MessageId another_id = 3; + */ + value: MessageId; + case: "anotherId"; + } | { case: undefined; value?: undefined }; +}; + +/** + * Describes the message test.UserId. + * Use `create(UserIdSchema)` to create a new message. + */ +export const UserIdSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_test_schemaregistry_serde_nested, 0); + +/** + * @generated from message test.MessageId + */ +export type MessageId = Message<"test.MessageId"> & { + /** + * @generated from field: string id = 1; + */ + id: string; +}; + +/** + * Describes the message test.MessageId. + * Use `create(MessageIdSchema)` to create a new message. + */ +export const MessageIdSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_test_schemaregistry_serde_nested, 1); + +/** + * @generated from message test.ComplexType + */ +export type ComplexType = Message<"test.ComplexType"> & { + /** + * @generated from oneof test.ComplexType.some_val + */ + someVal: { + /** + * @generated from field: string one_id = 1; + */ + value: string; + case: "oneId"; + } | { + /** + * @generated from field: int32 other_id = 2; + */ + value: number; + case: "otherId"; + } | { case: undefined; value?: undefined }; + + /** + * @generated from field: bool is_active = 3; + */ + isActive: boolean; +}; + +/** + * Describes the message test.ComplexType. + * Use `create(ComplexTypeSchema)` to create a new message. + */ +export const ComplexTypeSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_test_schemaregistry_serde_nested, 2); + +/** + * + * Complex message using nested protos and repeated fields + * + * @generated from message test.NestedMessage + */ +export type NestedMessage = Message<"test.NestedMessage"> & { + /** + * @generated from field: test.UserId user_id = 1; + */ + userId?: UserId; + + /** + * @generated from field: bool is_active = 2; + */ + isActive: boolean; + + /** + * @generated from field: repeated string experiments_active = 3; + */ + experimentsActive: string[]; + + /** + * @generated from field: google.protobuf.Timestamp updated_at = 4; + */ + updatedAt?: Timestamp; + + /** + * @generated from field: test.Status status = 5; + */ + status: Status; + + /** + * @generated from field: test.ComplexType complex_type = 6; + */ + complexType?: ComplexType; + + /** + * @generated from field: map map_type = 7; + */ + mapType: { [key: string]: string }; + + /** + * @generated from field: test.NestedMessage.InnerMessage inner = 8; + */ + inner?: NestedMessage_InnerMessage; +}; + +/** + * Describes the message test.NestedMessage. + * Use `create(NestedMessageSchema)` to create a new message. + */ +export const NestedMessageSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_test_schemaregistry_serde_nested, 3); + +/** + * @generated from message test.NestedMessage.InnerMessage + */ +export type NestedMessage_InnerMessage = Message<"test.NestedMessage.InnerMessage"> & { + /** + * @generated from field: string id = 1; + */ + id: string; + + /** + * @generated from field: repeated int32 ids = 2 [packed = true]; + */ + ids: number[]; +}; + +/** + * Describes the message test.NestedMessage.InnerMessage. + * Use `create(NestedMessage_InnerMessageSchema)` to create a new message. + */ +export const NestedMessage_InnerMessageSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_test_schemaregistry_serde_nested, 3, 0); + +/** + * @generated from enum test.NestedMessage.InnerEnum + */ +export enum NestedMessage_InnerEnum { + /** + * @generated from enum value: ZERO = 0; + */ + ZERO = 0, + + /** + * @generated from enum value: ALSO_ZERO = 0; + */ + ALSO_ZERO = 0, +} + +/** + * Describes the enum test.NestedMessage.InnerEnum. + */ +export const NestedMessage_InnerEnumSchema: GenEnum = /*@__PURE__*/ + enumDesc(file_test_schemaregistry_serde_nested, 3, 0); + +/** + * @generated from enum test.Status + */ +export enum Status { + /** + * @generated from enum value: ACTIVE = 0; + */ + ACTIVE = 0, + + /** + * @generated from enum value: INACTIVE = 1; + */ + INACTIVE = 1, +} + +/** + * Describes the enum test.Status. + */ +export const StatusSchema: GenEnum = /*@__PURE__*/ + enumDesc(file_test_schemaregistry_serde_nested, 0); + diff --git a/test/schemaregistry/serde/test/newerwidget_pb.ts b/test/schemaregistry/serde/test/newerwidget_pb.ts new file mode 100644 index 00000000..69749e4d --- /dev/null +++ b/test/schemaregistry/serde/test/newerwidget_pb.ts @@ -0,0 +1,41 @@ +// @generated by protoc-gen-es v2.0.0 with parameter "target=ts" +// @generated from file test/schemaregistry/serde/newerwidget.proto (package test, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file test/schemaregistry/serde/newerwidget.proto. + */ +export const file_test_schemaregistry_serde_newerwidget: GenFile = /*@__PURE__*/ + fileDesc("Cit0ZXN0L3NjaGVtYXJlZ2lzdHJ5L3NlcmRlL25ld2Vyd2lkZ2V0LnByb3RvEgR0ZXN0IjwKC05ld2VyV2lkZ2V0EgwKBG5hbWUYASABKAkSDgoGbGVuZ3RoGAIgASgFEg8KB3ZlcnNpb24YAyABKAVCCVoHLi4vdGVzdGIGcHJvdG8z"); + +/** + * @generated from message test.NewerWidget + */ +export type NewerWidget = Message<"test.NewerWidget"> & { + /** + * @generated from field: string name = 1; + */ + name: string; + + /** + * @generated from field: int32 length = 2; + */ + length: number; + + /** + * @generated from field: int32 version = 3; + */ + version: number; +}; + +/** + * Describes the message test.NewerWidget. + * Use `create(NewerWidgetSchema)` to create a new message. + */ +export const NewerWidgetSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_test_schemaregistry_serde_newerwidget, 0); + diff --git a/test/schemaregistry/serde/test/newwidget_pb.ts b/test/schemaregistry/serde/test/newwidget_pb.ts new file mode 100644 index 00000000..a24ad209 --- /dev/null +++ b/test/schemaregistry/serde/test/newwidget_pb.ts @@ -0,0 +1,41 @@ +// @generated by protoc-gen-es v2.0.0 with parameter "target=ts" +// @generated from file test/schemaregistry/serde/newwidget.proto (package test, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file test/schemaregistry/serde/newwidget.proto. + */ +export const file_test_schemaregistry_serde_newwidget: GenFile = /*@__PURE__*/ + fileDesc("Cil0ZXN0L3NjaGVtYXJlZ2lzdHJ5L3NlcmRlL25ld3dpZGdldC5wcm90bxIEdGVzdCI6CglOZXdXaWRnZXQSDAoEbmFtZRgBIAEoCRIOCgZoZWlnaHQYAiABKAUSDwoHdmVyc2lvbhgDIAEoBUIJWgcuLi90ZXN0YgZwcm90bzM"); + +/** + * @generated from message test.NewWidget + */ +export type NewWidget = Message<"test.NewWidget"> & { + /** + * @generated from field: string name = 1; + */ + name: string; + + /** + * @generated from field: int32 height = 2; + */ + height: number; + + /** + * @generated from field: int32 version = 3; + */ + version: number; +}; + +/** + * Describes the message test.NewWidget. + * Use `create(NewWidgetSchema)` to create a new message. + */ +export const NewWidgetSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_test_schemaregistry_serde_newwidget, 0); + diff --git a/test/schemaregistry/serde/test/test_pb.ts b/test/schemaregistry/serde/test/test_pb.ts new file mode 100644 index 00000000..09126158 --- /dev/null +++ b/test/schemaregistry/serde/test/test_pb.ts @@ -0,0 +1,102 @@ +// @generated by protoc-gen-es v2.0.0 with parameter "target=ts" +// @generated from file test/schemaregistry/serde/test.proto (package test, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import { file_google_protobuf_descriptor } from "@bufbuild/protobuf/wkt"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file test/schemaregistry/serde/test.proto. + */ +export const file_test_schemaregistry_serde_test: GenFile = /*@__PURE__*/ + fileDesc("CiR0ZXN0L3NjaGVtYXJlZ2lzdHJ5L3NlcmRlL3Rlc3QucHJvdG8SBHRlc3QiyAIKC1Rlc3RNZXNzYWdlEhMKC3Rlc3Rfc3RyaW5nGAEgASgJEhEKCXRlc3RfYm9vbBgCIAEoCBISCgp0ZXN0X2J5dGVzGAMgASgMEhMKC3Rlc3RfZG91YmxlGAQgASgBEhIKCnRlc3RfZmxvYXQYBSABKAISFAoMdGVzdF9maXhlZDMyGAYgASgHEhQKDHRlc3RfZml4ZWQ2NBgHIAEoBhISCgp0ZXN0X2ludDMyGAggASgFEhIKCnRlc3RfaW50NjQYCSABKAMSFQoNdGVzdF9zZml4ZWQzMhgKIAEoDxIVCg10ZXN0X3NmaXhlZDY0GAsgASgQEhMKC3Rlc3Rfc2ludDMyGAwgASgREhMKC3Rlc3Rfc2ludDY0GA0gASgSEhMKC3Rlc3RfdWludDMyGA4gASgNEhMKC3Rlc3RfdWludDY0GA8gASgEQglaBy4uL3Rlc3RiBnByb3RvMw", [file_google_protobuf_descriptor]); + +/** + * @generated from message test.TestMessage + */ +export type TestMessage = Message<"test.TestMessage"> & { + /** + * @generated from field: string test_string = 1; + */ + testString: string; + + /** + * @generated from field: bool test_bool = 2; + */ + testBool: boolean; + + /** + * @generated from field: bytes test_bytes = 3; + */ + testBytes: Uint8Array; + + /** + * @generated from field: double test_double = 4; + */ + testDouble: number; + + /** + * @generated from field: float test_float = 5; + */ + testFloat: number; + + /** + * @generated from field: fixed32 test_fixed32 = 6; + */ + testFixed32: number; + + /** + * @generated from field: fixed64 test_fixed64 = 7; + */ + testFixed64: bigint; + + /** + * @generated from field: int32 test_int32 = 8; + */ + testInt32: number; + + /** + * @generated from field: int64 test_int64 = 9; + */ + testInt64: bigint; + + /** + * @generated from field: sfixed32 test_sfixed32 = 10; + */ + testSfixed32: number; + + /** + * @generated from field: sfixed64 test_sfixed64 = 11; + */ + testSfixed64: bigint; + + /** + * @generated from field: sint32 test_sint32 = 12; + */ + testSint32: number; + + /** + * @generated from field: sint64 test_sint64 = 13; + */ + testSint64: bigint; + + /** + * @generated from field: uint32 test_uint32 = 14; + */ + testUint32: number; + + /** + * @generated from field: uint64 test_uint64 = 15; + */ + testUint64: bigint; +}; + +/** + * Describes the message test.TestMessage. + * Use `create(TestMessageSchema)` to create a new message. + */ +export const TestMessageSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_test_schemaregistry_serde_test, 0); + diff --git a/test/schemaregistry/serde/test/widget_pb.ts b/test/schemaregistry/serde/test/widget_pb.ts new file mode 100644 index 00000000..a8924d86 --- /dev/null +++ b/test/schemaregistry/serde/test/widget_pb.ts @@ -0,0 +1,41 @@ +// @generated by protoc-gen-es v2.0.0 with parameter "target=ts" +// @generated from file test/schemaregistry/serde/widget.proto (package test, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv1"; +import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file test/schemaregistry/serde/widget.proto. + */ +export const file_test_schemaregistry_serde_widget: GenFile = /*@__PURE__*/ + fileDesc("CiZ0ZXN0L3NjaGVtYXJlZ2lzdHJ5L3NlcmRlL3dpZGdldC5wcm90bxIEdGVzdCI1CgZXaWRnZXQSDAoEbmFtZRgBIAEoCRIMCgRzaXplGAIgASgFEg8KB3ZlcnNpb24YAyABKAVCCVoHLi4vdGVzdGIGcHJvdG8z"); + +/** + * @generated from message test.Widget + */ +export type Widget = Message<"test.Widget"> & { + /** + * @generated from field: string name = 1; + */ + name: string; + + /** + * @generated from field: int32 size = 2; + */ + size: number; + + /** + * @generated from field: int32 version = 3; + */ + version: number; +}; + +/** + * Describes the message test.Widget. + * Use `create(WidgetSchema)` to create a new message. + */ +export const WidgetSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_test_schemaregistry_serde_widget, 0); +