diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c284855c..ff6d374a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -132,7 +132,8 @@ jobs: - name: Verify generated code is current run: | - go run github.com/bufbuild/buf/cmd/buf@v1.59.0 generate + go run github.com/bufbuild/buf/cmd/buf@v1.59.0 generate --template buf.gen.go.yaml --exclude-path proto/cerebro + go run github.com/bufbuild/buf/cmd/buf@v1.59.0 generate --template buf.gen.ts.yaml git diff --exit-code -- gen packages/connect/src/gen test -z "$(git status --porcelain -- gen packages/connect/src/gen)" diff --git a/.github/workflows/contracts.yml b/.github/workflows/contracts.yml index 2d54cabe..9041c6c9 100644 --- a/.github/workflows/contracts.yml +++ b/.github/workflows/contracts.yml @@ -5,7 +5,8 @@ on: paths: - "proto/**" - "buf.yaml" - - "buf.gen.yaml" + - "buf.gen.go.yaml" + - "buf.gen.ts.yaml" - "gen/**" - "packages/connect/src/gen/**" - ".github/workflows/contracts.yml" @@ -36,6 +37,7 @@ jobs: - name: Verify generated outputs run: | - go run github.com/bufbuild/buf/cmd/buf@v1.59.0 generate + go run github.com/bufbuild/buf/cmd/buf@v1.59.0 generate --template buf.gen.go.yaml --exclude-path proto/cerebro + go run github.com/bufbuild/buf/cmd/buf@v1.59.0 generate --template buf.gen.ts.yaml git diff --exit-code -- gen packages/connect/src/gen test -z "$(git status --porcelain -- gen packages/connect/src/gen)" diff --git a/.github/workflows/droid-create.yml b/.github/workflows/droid-create.yml index 7ea8c7e1..080b1483 100644 --- a/.github/workflows/droid-create.yml +++ b/.github/workflows/droid-create.yml @@ -739,7 +739,8 @@ jobs: npm run db:validate go mod download go run github.com/bufbuild/buf/cmd/buf@v1.59.0 lint - go run github.com/bufbuild/buf/cmd/buf@v1.59.0 generate + go run github.com/bufbuild/buf/cmd/buf@v1.59.0 generate --template buf.gen.go.yaml --exclude-path proto/cerebro + go run github.com/bufbuild/buf/cmd/buf@v1.59.0 generate --template buf.gen.ts.yaml git diff --exit-code -- gen packages/connect/src/gen test -z "$(git status --porcelain -- gen packages/connect/src/gen)" make lint diff --git a/Makefile b/Makefile index 2e144537..38490cec 100644 --- a/Makefile +++ b/Makefile @@ -238,7 +238,8 @@ db-validate: ## Validate the Prisma schema .PHONY: generate generate: ## Regenerate Go + TypeScript protobuf clients (needs network) - @go run github.com/bufbuild/buf/cmd/buf@$(BUF_VERSION) generate + @go run github.com/bufbuild/buf/cmd/buf@$(BUF_VERSION) generate --template buf.gen.go.yaml --exclude-path proto/cerebro + @go run github.com/bufbuild/buf/cmd/buf@$(BUF_VERSION) generate --template buf.gen.ts.yaml .PHONY: generate-check generate-check: generate ## Verify the generated clients are up to date diff --git a/buf.gen.yaml b/buf.gen.go.yaml similarity index 70% rename from buf.gen.yaml rename to buf.gen.go.yaml index 72b4aefa..739e5386 100644 --- a/buf.gen.yaml +++ b/buf.gen.go.yaml @@ -9,7 +9,3 @@ plugins: opt: - paths=source_relative - package_suffix=connect - - remote: buf.build/bufbuild/es:v2.10.0 - out: packages/connect/src/gen - opt: - - target=ts diff --git a/buf.gen.ts.yaml b/buf.gen.ts.yaml new file mode 100644 index 00000000..87e9bf4d --- /dev/null +++ b/buf.gen.ts.yaml @@ -0,0 +1,6 @@ +version: v2 +plugins: + - remote: buf.build/bufbuild/es:v2.10.0 + out: packages/connect/src/gen + opt: + - target=ts diff --git a/buf.yaml b/buf.yaml index c7e30e38..c32839af 100644 --- a/buf.yaml +++ b/buf.yaml @@ -7,3 +7,7 @@ lint: breaking: use: - FILE + except: + # cerebro/v1 go_package is intentionally repointed to the shared Cerebro Go + # SDK module; the wire contract is unchanged. + - FILE_SAME_GO_PACKAGE diff --git a/gen/aperio/contracts/v1/events.pb.go b/gen/aperio/contracts/v1/events.pb.go index 5cc35eb3..8f5e2650 100644 --- a/gen/aperio/contracts/v1/events.pb.go +++ b/gen/aperio/contracts/v1/events.pb.go @@ -7,7 +7,7 @@ package aperiocontractsv1 import ( - v1 "github.com/writer/aperio/gen/cerebro/v1" + v1 "github.com/writer/cerebro/sdk/go/cerebroapi/genproto/cerebro/v1" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" diff --git a/gen/cerebro/v1/primitives.pb.go b/gen/cerebro/v1/primitives.pb.go deleted file mode 100644 index 7a852453..00000000 --- a/gen/cerebro/v1/primitives.pb.go +++ /dev/null @@ -1,448 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.11 -// protoc (unknown) -// source: cerebro/v1/primitives.proto - -package cerebrov1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" - unsafe "unsafe" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type EventEnvelope struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - TenantId string `protobuf:"bytes,2,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"` - SourceId string `protobuf:"bytes,3,opt,name=source_id,json=sourceId,proto3" json:"source_id,omitempty"` - Kind string `protobuf:"bytes,4,opt,name=kind,proto3" json:"kind,omitempty"` - OccurredAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=occurred_at,json=occurredAt,proto3" json:"occurred_at,omitempty"` - SchemaRef string `protobuf:"bytes,6,opt,name=schema_ref,json=schemaRef,proto3" json:"schema_ref,omitempty"` - Payload []byte `protobuf:"bytes,7,opt,name=payload,proto3" json:"payload,omitempty"` - Attributes map[string]string `protobuf:"bytes,8,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *EventEnvelope) Reset() { - *x = EventEnvelope{} - mi := &file_cerebro_v1_primitives_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *EventEnvelope) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EventEnvelope) ProtoMessage() {} - -func (x *EventEnvelope) ProtoReflect() protoreflect.Message { - mi := &file_cerebro_v1_primitives_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EventEnvelope.ProtoReflect.Descriptor instead. -func (*EventEnvelope) Descriptor() ([]byte, []int) { - return file_cerebro_v1_primitives_proto_rawDescGZIP(), []int{0} -} - -func (x *EventEnvelope) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *EventEnvelope) GetTenantId() string { - if x != nil { - return x.TenantId - } - return "" -} - -func (x *EventEnvelope) GetSourceId() string { - if x != nil { - return x.SourceId - } - return "" -} - -func (x *EventEnvelope) GetKind() string { - if x != nil { - return x.Kind - } - return "" -} - -func (x *EventEnvelope) GetOccurredAt() *timestamppb.Timestamp { - if x != nil { - return x.OccurredAt - } - return nil -} - -func (x *EventEnvelope) GetSchemaRef() string { - if x != nil { - return x.SchemaRef - } - return "" -} - -func (x *EventEnvelope) GetPayload() []byte { - if x != nil { - return x.Payload - } - return nil -} - -func (x *EventEnvelope) GetAttributes() map[string]string { - if x != nil { - return x.Attributes - } - return nil -} - -type EntityRef struct { - state protoimpl.MessageState `protogen:"open.v1"` - Urn string `protobuf:"bytes,1,opt,name=urn,proto3" json:"urn,omitempty"` - EntityType string `protobuf:"bytes,2,opt,name=entity_type,json=entityType,proto3" json:"entity_type,omitempty"` - Label string `protobuf:"bytes,3,opt,name=label,proto3" json:"label,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *EntityRef) Reset() { - *x = EntityRef{} - mi := &file_cerebro_v1_primitives_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *EntityRef) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*EntityRef) ProtoMessage() {} - -func (x *EntityRef) ProtoReflect() protoreflect.Message { - mi := &file_cerebro_v1_primitives_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use EntityRef.ProtoReflect.Descriptor instead. -func (*EntityRef) Descriptor() ([]byte, []int) { - return file_cerebro_v1_primitives_proto_rawDescGZIP(), []int{1} -} - -func (x *EntityRef) GetUrn() string { - if x != nil { - return x.Urn - } - return "" -} - -func (x *EntityRef) GetEntityType() string { - if x != nil { - return x.EntityType - } - return "" -} - -func (x *EntityRef) GetLabel() string { - if x != nil { - return x.Label - } - return "" -} - -type Claim struct { - state protoimpl.MessageState `protogen:"open.v1"` - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - SubjectUrn string `protobuf:"bytes,2,opt,name=subject_urn,json=subjectUrn,proto3" json:"subject_urn,omitempty"` - SubjectRef *EntityRef `protobuf:"bytes,3,opt,name=subject_ref,json=subjectRef,proto3" json:"subject_ref,omitempty"` - Predicate string `protobuf:"bytes,4,opt,name=predicate,proto3" json:"predicate,omitempty"` - ObjectUrn string `protobuf:"bytes,5,opt,name=object_urn,json=objectUrn,proto3" json:"object_urn,omitempty"` - ObjectRef *EntityRef `protobuf:"bytes,6,opt,name=object_ref,json=objectRef,proto3" json:"object_ref,omitempty"` - ObjectValue string `protobuf:"bytes,7,opt,name=object_value,json=objectValue,proto3" json:"object_value,omitempty"` - ClaimType string `protobuf:"bytes,8,opt,name=claim_type,json=claimType,proto3" json:"claim_type,omitempty"` - Status string `protobuf:"bytes,9,opt,name=status,proto3" json:"status,omitempty"` - SourceEventId string `protobuf:"bytes,10,opt,name=source_event_id,json=sourceEventId,proto3" json:"source_event_id,omitempty"` - ObservedAt *timestamppb.Timestamp `protobuf:"bytes,11,opt,name=observed_at,json=observedAt,proto3" json:"observed_at,omitempty"` - ValidFrom *timestamppb.Timestamp `protobuf:"bytes,12,opt,name=valid_from,json=validFrom,proto3" json:"valid_from,omitempty"` - ValidTo *timestamppb.Timestamp `protobuf:"bytes,13,opt,name=valid_to,json=validTo,proto3" json:"valid_to,omitempty"` - Attributes map[string]string `protobuf:"bytes,14,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Claim) Reset() { - *x = Claim{} - mi := &file_cerebro_v1_primitives_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Claim) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Claim) ProtoMessage() {} - -func (x *Claim) ProtoReflect() protoreflect.Message { - mi := &file_cerebro_v1_primitives_proto_msgTypes[2] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Claim.ProtoReflect.Descriptor instead. -func (*Claim) Descriptor() ([]byte, []int) { - return file_cerebro_v1_primitives_proto_rawDescGZIP(), []int{2} -} - -func (x *Claim) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *Claim) GetSubjectUrn() string { - if x != nil { - return x.SubjectUrn - } - return "" -} - -func (x *Claim) GetSubjectRef() *EntityRef { - if x != nil { - return x.SubjectRef - } - return nil -} - -func (x *Claim) GetPredicate() string { - if x != nil { - return x.Predicate - } - return "" -} - -func (x *Claim) GetObjectUrn() string { - if x != nil { - return x.ObjectUrn - } - return "" -} - -func (x *Claim) GetObjectRef() *EntityRef { - if x != nil { - return x.ObjectRef - } - return nil -} - -func (x *Claim) GetObjectValue() string { - if x != nil { - return x.ObjectValue - } - return "" -} - -func (x *Claim) GetClaimType() string { - if x != nil { - return x.ClaimType - } - return "" -} - -func (x *Claim) GetStatus() string { - if x != nil { - return x.Status - } - return "" -} - -func (x *Claim) GetSourceEventId() string { - if x != nil { - return x.SourceEventId - } - return "" -} - -func (x *Claim) GetObservedAt() *timestamppb.Timestamp { - if x != nil { - return x.ObservedAt - } - return nil -} - -func (x *Claim) GetValidFrom() *timestamppb.Timestamp { - if x != nil { - return x.ValidFrom - } - return nil -} - -func (x *Claim) GetValidTo() *timestamppb.Timestamp { - if x != nil { - return x.ValidTo - } - return nil -} - -func (x *Claim) GetAttributes() map[string]string { - if x != nil { - return x.Attributes - } - return nil -} - -var File_cerebro_v1_primitives_proto protoreflect.FileDescriptor - -const file_cerebro_v1_primitives_proto_rawDesc = "" + - "\n" + - "\x1bcerebro/v1/primitives.proto\x12\n" + - "cerebro.v1\x1a\x1fgoogle/protobuf/timestamp.proto\"\xed\x02\n" + - "\rEventEnvelope\x12\x0e\n" + - "\x02id\x18\x01 \x01(\tR\x02id\x12\x1b\n" + - "\ttenant_id\x18\x02 \x01(\tR\btenantId\x12\x1b\n" + - "\tsource_id\x18\x03 \x01(\tR\bsourceId\x12\x12\n" + - "\x04kind\x18\x04 \x01(\tR\x04kind\x12;\n" + - "\voccurred_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\n" + - "occurredAt\x12\x1d\n" + - "\n" + - "schema_ref\x18\x06 \x01(\tR\tschemaRef\x12\x18\n" + - "\apayload\x18\a \x01(\fR\apayload\x12I\n" + - "\n" + - "attributes\x18\b \x03(\v2).cerebro.v1.EventEnvelope.AttributesEntryR\n" + - "attributes\x1a=\n" + - "\x0fAttributesEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"T\n" + - "\tEntityRef\x12\x10\n" + - "\x03urn\x18\x01 \x01(\tR\x03urn\x12\x1f\n" + - "\ventity_type\x18\x02 \x01(\tR\n" + - "entityType\x12\x14\n" + - "\x05label\x18\x03 \x01(\tR\x05label\"\x96\x05\n" + - "\x05Claim\x12\x0e\n" + - "\x02id\x18\x01 \x01(\tR\x02id\x12\x1f\n" + - "\vsubject_urn\x18\x02 \x01(\tR\n" + - "subjectUrn\x126\n" + - "\vsubject_ref\x18\x03 \x01(\v2\x15.cerebro.v1.EntityRefR\n" + - "subjectRef\x12\x1c\n" + - "\tpredicate\x18\x04 \x01(\tR\tpredicate\x12\x1d\n" + - "\n" + - "object_urn\x18\x05 \x01(\tR\tobjectUrn\x124\n" + - "\n" + - "object_ref\x18\x06 \x01(\v2\x15.cerebro.v1.EntityRefR\tobjectRef\x12!\n" + - "\fobject_value\x18\a \x01(\tR\vobjectValue\x12\x1d\n" + - "\n" + - "claim_type\x18\b \x01(\tR\tclaimType\x12\x16\n" + - "\x06status\x18\t \x01(\tR\x06status\x12&\n" + - "\x0fsource_event_id\x18\n" + - " \x01(\tR\rsourceEventId\x12;\n" + - "\vobserved_at\x18\v \x01(\v2\x1a.google.protobuf.TimestampR\n" + - "observedAt\x129\n" + - "\n" + - "valid_from\x18\f \x01(\v2\x1a.google.protobuf.TimestampR\tvalidFrom\x125\n" + - "\bvalid_to\x18\r \x01(\v2\x1a.google.protobuf.TimestampR\avalidTo\x12A\n" + - "\n" + - "attributes\x18\x0e \x03(\v2!.cerebro.v1.Claim.AttributesEntryR\n" + - "attributes\x1a=\n" + - "\x0fAttributesEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01B3Z1github.com/writer/aperio/gen/cerebro/v1;cerebrov1b\x06proto3" - -var ( - file_cerebro_v1_primitives_proto_rawDescOnce sync.Once - file_cerebro_v1_primitives_proto_rawDescData []byte -) - -func file_cerebro_v1_primitives_proto_rawDescGZIP() []byte { - file_cerebro_v1_primitives_proto_rawDescOnce.Do(func() { - file_cerebro_v1_primitives_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_cerebro_v1_primitives_proto_rawDesc), len(file_cerebro_v1_primitives_proto_rawDesc))) - }) - return file_cerebro_v1_primitives_proto_rawDescData -} - -var file_cerebro_v1_primitives_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_cerebro_v1_primitives_proto_goTypes = []any{ - (*EventEnvelope)(nil), // 0: cerebro.v1.EventEnvelope - (*EntityRef)(nil), // 1: cerebro.v1.EntityRef - (*Claim)(nil), // 2: cerebro.v1.Claim - nil, // 3: cerebro.v1.EventEnvelope.AttributesEntry - nil, // 4: cerebro.v1.Claim.AttributesEntry - (*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp -} -var file_cerebro_v1_primitives_proto_depIdxs = []int32{ - 5, // 0: cerebro.v1.EventEnvelope.occurred_at:type_name -> google.protobuf.Timestamp - 3, // 1: cerebro.v1.EventEnvelope.attributes:type_name -> cerebro.v1.EventEnvelope.AttributesEntry - 1, // 2: cerebro.v1.Claim.subject_ref:type_name -> cerebro.v1.EntityRef - 1, // 3: cerebro.v1.Claim.object_ref:type_name -> cerebro.v1.EntityRef - 5, // 4: cerebro.v1.Claim.observed_at:type_name -> google.protobuf.Timestamp - 5, // 5: cerebro.v1.Claim.valid_from:type_name -> google.protobuf.Timestamp - 5, // 6: cerebro.v1.Claim.valid_to:type_name -> google.protobuf.Timestamp - 4, // 7: cerebro.v1.Claim.attributes:type_name -> cerebro.v1.Claim.AttributesEntry - 8, // [8:8] is the sub-list for method output_type - 8, // [8:8] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name -} - -func init() { file_cerebro_v1_primitives_proto_init() } -func file_cerebro_v1_primitives_proto_init() { - if File_cerebro_v1_primitives_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_cerebro_v1_primitives_proto_rawDesc), len(file_cerebro_v1_primitives_proto_rawDesc)), - NumEnums: 0, - NumMessages: 5, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_cerebro_v1_primitives_proto_goTypes, - DependencyIndexes: file_cerebro_v1_primitives_proto_depIdxs, - MessageInfos: file_cerebro_v1_primitives_proto_msgTypes, - }.Build() - File_cerebro_v1_primitives_proto = out.File - file_cerebro_v1_primitives_proto_goTypes = nil - file_cerebro_v1_primitives_proto_depIdxs = nil -} diff --git a/go.mod b/go.mod index 39c4cfd7..702a726f 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/go-pdf/fpdf v0.9.0 github.com/jackc/pgx/v5 v5.10.0 github.com/nats-io/nats.go v1.52.0 - github.com/writer/cerebro/sdk/go/cerebroapi v0.0.0-20260617165858-b79a38afb59c + github.com/writer/cerebro/sdk/go/cerebroapi v0.0.0-20260617190440-784f5eee34f2 golang.org/x/crypto v0.53.0 google.golang.org/protobuf v1.36.11 ) diff --git a/go.sum b/go.sum index e1d4b36d..5eac4878 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/writer/cerebro/sdk/go/cerebroapi v0.0.0-20260617165858-b79a38afb59c h1:Q4lzmWx5TNGG6wVyXFkc50QYk55wfzr4CZeC10m6XsE= -github.com/writer/cerebro/sdk/go/cerebroapi v0.0.0-20260617165858-b79a38afb59c/go.mod h1:Pj6RePoAtQMzYIZuYdS02A0RZInNozjLDKmEig8JlZM= +github.com/writer/cerebro/sdk/go/cerebroapi v0.0.0-20260617190440-784f5eee34f2 h1:+Jsrg6W9h3uUA8wt3N2hXtC3ZbiVVbvrPdIR01ClEXQ= +github.com/writer/cerebro/sdk/go/cerebroapi v0.0.0-20260617190440-784f5eee34f2/go.mod h1:dHVu/CuhHRejAdS2yHB7oBCnfeT9ZVD4yxDHdPPzmhw= golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto= golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio= golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= diff --git a/internal/bootstrap/event_bus.go b/internal/bootstrap/event_bus.go index 7b27d281..a15f83d9 100644 --- a/internal/bootstrap/event_bus.go +++ b/internal/bootstrap/event_bus.go @@ -9,7 +9,7 @@ import ( "github.com/nats-io/nats.go" aperiocontractsv1 "github.com/writer/aperio/gen/aperio/contracts/v1" - cerebrov1 "github.com/writer/aperio/gen/cerebro/v1" + cerebrov1 "github.com/writer/cerebro/sdk/go/cerebroapi/genproto/cerebro/v1" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" ) diff --git a/internal/bootstrap/finding_cerebro_context.go b/internal/bootstrap/finding_cerebro_context.go index a8775435..009553ce 100644 --- a/internal/bootstrap/finding_cerebro_context.go +++ b/internal/bootstrap/finding_cerebro_context.go @@ -6,8 +6,8 @@ import ( "strings" aperiov1 "github.com/writer/aperio/gen/aperio/v1" - cerebrov1 "github.com/writer/aperio/gen/cerebro/v1" "github.com/writer/aperio/internal/cerebroclient" + cerebrov1 "github.com/writer/cerebro/sdk/go/cerebroapi/genproto/cerebro/v1" ) const ( diff --git a/internal/bootstrap/saas_cerebro_context.go b/internal/bootstrap/saas_cerebro_context.go index e631bdda..fbd6fa53 100644 --- a/internal/bootstrap/saas_cerebro_context.go +++ b/internal/bootstrap/saas_cerebro_context.go @@ -6,8 +6,8 @@ import ( "fmt" "strings" - cerebrov1 "github.com/writer/aperio/gen/cerebro/v1" "github.com/writer/aperio/internal/cerebroclient" + cerebrov1 "github.com/writer/cerebro/sdk/go/cerebroapi/genproto/cerebro/v1" ) const ( diff --git a/internal/bootstrap/security_cerebro_context.go b/internal/bootstrap/security_cerebro_context.go index 7a930bf1..71755483 100644 --- a/internal/bootstrap/security_cerebro_context.go +++ b/internal/bootstrap/security_cerebro_context.go @@ -6,8 +6,8 @@ import ( "strings" "time" - cerebrov1 "github.com/writer/aperio/gen/cerebro/v1" "github.com/writer/aperio/internal/cerebroclient" + cerebrov1 "github.com/writer/cerebro/sdk/go/cerebroapi/genproto/cerebro/v1" ) const ( diff --git a/internal/cerebroclaims/builder.go b/internal/cerebroclaims/builder.go index c1b6002f..41faa037 100644 --- a/internal/cerebroclaims/builder.go +++ b/internal/cerebroclaims/builder.go @@ -9,9 +9,9 @@ import ( "strconv" "strings" - cerebrov1 "github.com/writer/aperio/gen/cerebro/v1" "github.com/writer/aperio/internal/cerebroclient" sdkclaims "github.com/writer/cerebro/sdk/go/cerebroapi/claims" + cerebrov1 "github.com/writer/cerebro/sdk/go/cerebroapi/genproto/cerebro/v1" ) type Payload struct { @@ -112,35 +112,12 @@ func Ref(organizationID, runtimeID, entityType, externalID, label string) cerebr } } +// EncodeExternalID preserves Aperio's historical URN segment encoding, where a +// space maps to '-'. It delegates to the SDK's legacy encoder; switching to the +// canonical percent encoder would orphan Cerebro URNs already persisted by +// Aperio. func EncodeExternalID(value string) string { - const upperHex = "0123456789ABCDEF" - var builder strings.Builder - for index := 0; index < len(value); index++ { - character := value[index] - if (character >= 'A' && character <= 'Z') || - (character >= 'a' && character <= 'z') || - (character >= '0' && character <= '9') || - character == '-' || - character == '_' || - character == '.' || - character == '!' || - character == '~' || - character == '*' || - character == '\'' || - character == '(' || - character == ')' { - builder.WriteByte(character) - continue - } - if character == ' ' { - builder.WriteByte('-') - continue - } - builder.WriteByte('%') - builder.WriteByte(upperHex[character>>4]) - builder.WriteByte(upperHex[character&0x0f]) - } - return builder.String() + return sdkclaims.EncodeExternalIDLegacy(value) } func claimSource(payload Payload, attributes map[string]string) sdkclaims.Source { diff --git a/internal/cerebroclient/client_test.go b/internal/cerebroclient/client_test.go index b1cce019..94ab4191 100644 --- a/internal/cerebroclient/client_test.go +++ b/internal/cerebroclient/client_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - cerebrov1 "github.com/writer/aperio/gen/cerebro/v1" + cerebrov1 "github.com/writer/cerebro/sdk/go/cerebroapi/genproto/cerebro/v1" ) func TestConfigFromEnvDefaultsAndTrims(t *testing.T) { diff --git a/internal/cerebroclient/proto.go b/internal/cerebroclient/proto.go index 17671735..51daeb54 100644 --- a/internal/cerebroclient/proto.go +++ b/internal/cerebroclient/proto.go @@ -1,174 +1,19 @@ package cerebroclient -import ( - "context" - "strings" - "time" - - cerebrov1 "github.com/writer/aperio/gen/cerebro/v1" - "google.golang.org/protobuf/types/known/timestamppb" +import "github.com/writer/cerebro/sdk/go/cerebroapi" + +// Proto claim request/response types re-exported from the Cerebro SDK so +// Aperio call sites keep using the cerebroclient facade. The WriteProtoClaims +// and ListProtoClaims methods are promoted from the embedded *cerebroapi.Client. +type ( + WriteProtoClaimsRequest = cerebroapi.WriteProtoClaimsRequest + ListProtoClaimsResponse = cerebroapi.ListProtoClaimsResponse ) -type WriteProtoClaimsRequest struct { - RuntimeID string - Claims []*cerebrov1.Claim - ReplaceExisting bool -} - -type ListProtoClaimsResponse struct { - Claims []*cerebrov1.Claim -} - -func (c *Client) ListProtoClaims(ctx context.Context, request ListClaimsRequest) (*ListProtoClaimsResponse, error) { - response, err := c.ListClaims(ctx, request) - if err != nil { - return nil, err - } - if response == nil { - return &ListProtoClaimsResponse{}, nil - } - return &ListProtoClaimsResponse{ - Claims: ClaimsToProto(response.Claims), - }, nil -} - -func (c *Client) WriteProtoClaims(ctx context.Context, request WriteProtoClaimsRequest) (*WriteClaimsResponse, error) { - return c.WriteClaims(ctx, WriteClaimsRequest{ - RuntimeID: request.RuntimeID, - Claims: ClaimsFromProto(request.Claims), - ReplaceExisting: request.ReplaceExisting, - }) -} - -func ClaimToProto(claim Claim) *cerebrov1.Claim { - return &cerebrov1.Claim{ - Id: claim.ID, - SubjectUrn: claim.SubjectURN, - SubjectRef: EntityRefToProto(claim.SubjectRef), - Predicate: claim.Predicate, - ObjectUrn: claim.ObjectURN, - ObjectRef: OptionalEntityRefToProto(claim.ObjectRef), - ObjectValue: claim.ObjectValue, - ClaimType: claim.ClaimType, - Status: claim.Status, - SourceEventId: claim.SourceEventID, - ObservedAt: timestampFromRFC3339(claim.ObservedAt), - ValidFrom: timestampFromRFC3339(claim.ValidFrom), - ValidTo: timestampFromRFC3339(claim.ValidTo), - Attributes: compactAttributes(claim.Attributes), - } -} - -func ClaimsToProto(claims []Claim) []*cerebrov1.Claim { - out := make([]*cerebrov1.Claim, 0, len(claims)) - for _, claim := range claims { - out = append(out, ClaimToProto(claim)) - } - return out -} - -func ClaimFromProto(claim *cerebrov1.Claim) Claim { - if claim == nil { - return Claim{} - } - return Claim{ - ID: claim.GetId(), - SubjectURN: claim.GetSubjectUrn(), - SubjectRef: EntityRefFromProto(claim.GetSubjectRef()), - Predicate: claim.GetPredicate(), - ObjectURN: claim.GetObjectUrn(), - ObjectRef: OptionalEntityRefFromProto(claim.GetObjectRef()), - ObjectValue: claim.GetObjectValue(), - ClaimType: claim.GetClaimType(), - Status: claim.GetStatus(), - SourceEventID: claim.GetSourceEventId(), - ObservedAt: timestampToRFC3339(claim.GetObservedAt()), - ValidFrom: timestampToRFC3339(claim.GetValidFrom()), - ValidTo: timestampToRFC3339(claim.GetValidTo()), - Attributes: copyAttributes(claim.GetAttributes()), - } -} - -func ClaimsFromProto(claims []*cerebrov1.Claim) []Claim { - out := make([]Claim, 0, len(claims)) - for _, claim := range claims { - out = append(out, ClaimFromProto(claim)) - } - return out -} - -func EntityRefToProto(ref EntityRef) *cerebrov1.EntityRef { - if strings.TrimSpace(ref.URN) == "" && - strings.TrimSpace(ref.EntityType) == "" && - strings.TrimSpace(ref.Label) == "" { - return nil - } - return &cerebrov1.EntityRef{ - Urn: ref.URN, - EntityType: ref.EntityType, - Label: ref.Label, - } -} - -func OptionalEntityRefToProto(ref *EntityRef) *cerebrov1.EntityRef { - if ref == nil { - return nil - } - return EntityRefToProto(*ref) -} - -func EntityRefFromProto(ref *cerebrov1.EntityRef) EntityRef { - if ref == nil { - return EntityRef{} - } - return EntityRef{ - URN: ref.GetUrn(), - EntityType: ref.GetEntityType(), - Label: ref.GetLabel(), - } -} - -func OptionalEntityRefFromProto(ref *cerebrov1.EntityRef) *EntityRef { - if ref == nil { - return nil - } - converted := EntityRefFromProto(ref) - return &converted -} - -func timestampFromRFC3339(value string) *timestamppb.Timestamp { - trimmed := strings.TrimSpace(value) - if trimmed == "" { - return nil - } - parsed, err := time.Parse(time.RFC3339Nano, trimmed) - if err != nil { - return nil - } - return timestamppb.New(parsed) -} - -func timestampToRFC3339(value *timestamppb.Timestamp) string { - if value == nil || value.CheckValid() != nil { - return "" - } - return value.AsTime().UTC().Format(time.RFC3339Nano) -} - -func compactAttributes(attributes map[string]string) map[string]string { - out := map[string]string{} - for key, value := range attributes { - if trimmed := strings.TrimSpace(value); trimmed != "" { - out[key] = trimmed - } - } - return out -} - -func copyAttributes(attributes map[string]string) map[string]string { - out := map[string]string{} - for key, value := range attributes { - out[key] = value - } - return out -} +// Proto claim conversion helpers re-exported from the Cerebro SDK. +var ( + ClaimToProto = cerebroapi.ClaimToProto + ClaimsToProto = cerebroapi.ClaimsToProto + ClaimFromProto = cerebroapi.ClaimFromProto + ClaimsFromProto = cerebroapi.ClaimsFromProto +) diff --git a/internal/cerebroclient/proto_test.go b/internal/cerebroclient/proto_test.go index d1e98c08..f26bd773 100644 --- a/internal/cerebroclient/proto_test.go +++ b/internal/cerebroclient/proto_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - cerebrov1 "github.com/writer/aperio/gen/cerebro/v1" + cerebrov1 "github.com/writer/cerebro/sdk/go/cerebroapi/genproto/cerebro/v1" "google.golang.org/protobuf/types/known/timestamppb" ) diff --git a/internal/ingestionworker/event_bus.go b/internal/ingestionworker/event_bus.go index e07991c7..fff79aca 100644 --- a/internal/ingestionworker/event_bus.go +++ b/internal/ingestionworker/event_bus.go @@ -10,7 +10,7 @@ import ( "github.com/nats-io/nats.go" aperiocontractsv1 "github.com/writer/aperio/gen/aperio/contracts/v1" - cerebrov1 "github.com/writer/aperio/gen/cerebro/v1" + cerebrov1 "github.com/writer/cerebro/sdk/go/cerebroapi/genproto/cerebro/v1" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" ) diff --git a/internal/ingestionworker/event_bus_test.go b/internal/ingestionworker/event_bus_test.go index 576bad63..74263f98 100644 --- a/internal/ingestionworker/event_bus_test.go +++ b/internal/ingestionworker/event_bus_test.go @@ -10,7 +10,7 @@ import ( "github.com/nats-io/nats.go" aperiocontractsv1 "github.com/writer/aperio/gen/aperio/contracts/v1" - cerebrov1 "github.com/writer/aperio/gen/cerebro/v1" + cerebrov1 "github.com/writer/cerebro/sdk/go/cerebroapi/genproto/cerebro/v1" "google.golang.org/protobuf/proto" ) diff --git a/internal/siemdispatcher/event_bus.go b/internal/siemdispatcher/event_bus.go index 88e04d7b..da43aca6 100644 --- a/internal/siemdispatcher/event_bus.go +++ b/internal/siemdispatcher/event_bus.go @@ -9,8 +9,8 @@ import ( "github.com/nats-io/nats.go" aperiocontractsv1 "github.com/writer/aperio/gen/aperio/contracts/v1" - cerebrov1 "github.com/writer/aperio/gen/cerebro/v1" "github.com/writer/aperio/internal/cerebroclient" + cerebrov1 "github.com/writer/cerebro/sdk/go/cerebroapi/genproto/cerebro/v1" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" ) diff --git a/internal/siemdispatcher/event_bus_test.go b/internal/siemdispatcher/event_bus_test.go index 1c675fb1..3c4d6fe7 100644 --- a/internal/siemdispatcher/event_bus_test.go +++ b/internal/siemdispatcher/event_bus_test.go @@ -9,8 +9,8 @@ import ( "github.com/nats-io/nats.go" aperiocontractsv1 "github.com/writer/aperio/gen/aperio/contracts/v1" - cerebrov1 "github.com/writer/aperio/gen/cerebro/v1" "github.com/writer/aperio/internal/cerebroclient" + cerebrov1 "github.com/writer/cerebro/sdk/go/cerebroapi/genproto/cerebro/v1" "google.golang.org/protobuf/proto" ) diff --git a/package.json b/package.json index db7c5bfb..f520b2d6 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "test:api": "tsx --test tests/*.test.ts", "test:go": "go test ./...", "proto:lint": "go run github.com/bufbuild/buf/cmd/buf@v1.59.0 lint", - "proto:generate": "go run github.com/bufbuild/buf/cmd/buf@v1.59.0 generate", + "proto:generate": "go run github.com/bufbuild/buf/cmd/buf@v1.59.0 generate --template buf.gen.go.yaml --exclude-path proto/cerebro && go run github.com/bufbuild/buf/cmd/buf@v1.59.0 generate --template buf.gen.ts.yaml", "proto:check": "npm run proto:lint && npm run proto:generate && git add --intent-to-add -- gen packages/connect/src/gen && git diff --exit-code -- gen packages/connect/src/gen", "verify:go": "npm run proto:check && npm run test:go", "verify": "npm run db:generate && npm run typecheck && npm run guardrails:migration && npm run test:api && npm run db:validate && npm run proto:check && npm run test:go && unset DOCKER_HOST && make test-go-db && make lint && npm run build:web && make smoke-workers-go && npm run smoke:e2e && npm run audit:prod && npm run leak:check", diff --git a/packages/connect/src/gen/cerebro/v1/primitives_pb.ts b/packages/connect/src/gen/cerebro/v1/primitives_pb.ts index 26305672..99e4becd 100644 --- a/packages/connect/src/gen/cerebro/v1/primitives_pb.ts +++ b/packages/connect/src/gen/cerebro/v1/primitives_pb.ts @@ -12,7 +12,7 @@ import type { Message } from "@bufbuild/protobuf"; * Describes the file cerebro/v1/primitives.proto. */ export const file_cerebro_v1_primitives: GenFile = /*@__PURE__*/ - fileDesc("ChtjZXJlYnJvL3YxL3ByaW1pdGl2ZXMucHJvdG8SCmNlcmVicm8udjEilwIKDUV2ZW50RW52ZWxvcGUSCgoCaWQYASABKAkSEQoJdGVuYW50X2lkGAIgASgJEhEKCXNvdXJjZV9pZBgDIAEoCRIMCgRraW5kGAQgASgJEi8KC29jY3VycmVkX2F0GAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBISCgpzY2hlbWFfcmVmGAYgASgJEg8KB3BheWxvYWQYByABKAwSPQoKYXR0cmlidXRlcxgIIAMoCzIpLmNlcmVicm8udjEuRXZlbnRFbnZlbG9wZS5BdHRyaWJ1dGVzRW50cnkaMQoPQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEiPAoJRW50aXR5UmVmEgsKA3VybhgBIAEoCRITCgtlbnRpdHlfdHlwZRgCIAEoCRINCgVsYWJlbBgDIAEoCSLyAwoFQ2xhaW0SCgoCaWQYASABKAkSEwoLc3ViamVjdF91cm4YAiABKAkSKgoLc3ViamVjdF9yZWYYAyABKAsyFS5jZXJlYnJvLnYxLkVudGl0eVJlZhIRCglwcmVkaWNhdGUYBCABKAkSEgoKb2JqZWN0X3VybhgFIAEoCRIpCgpvYmplY3RfcmVmGAYgASgLMhUuY2VyZWJyby52MS5FbnRpdHlSZWYSFAoMb2JqZWN0X3ZhbHVlGAcgASgJEhIKCmNsYWltX3R5cGUYCCABKAkSDgoGc3RhdHVzGAkgASgJEhcKD3NvdXJjZV9ldmVudF9pZBgKIAEoCRIvCgtvYnNlcnZlZF9hdBgLIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLgoKdmFsaWRfZnJvbRgMIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLAoIdmFsaWRfdG8YDSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEjUKCmF0dHJpYnV0ZXMYDiADKAsyIS5jZXJlYnJvLnYxLkNsYWltLkF0dHJpYnV0ZXNFbnRyeRoxCg9BdHRyaWJ1dGVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4AUIzWjFnaXRodWIuY29tL3dyaXRlci9hcGVyaW8vZ2VuL2NlcmVicm8vdjE7Y2VyZWJyb3YxYgZwcm90bzM", [file_google_protobuf_timestamp]); + fileDesc("ChtjZXJlYnJvL3YxL3ByaW1pdGl2ZXMucHJvdG8SCmNlcmVicm8udjEilwIKDUV2ZW50RW52ZWxvcGUSCgoCaWQYASABKAkSEQoJdGVuYW50X2lkGAIgASgJEhEKCXNvdXJjZV9pZBgDIAEoCRIMCgRraW5kGAQgASgJEi8KC29jY3VycmVkX2F0GAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBISCgpzY2hlbWFfcmVmGAYgASgJEg8KB3BheWxvYWQYByABKAwSPQoKYXR0cmlidXRlcxgIIAMoCzIpLmNlcmVicm8udjEuRXZlbnRFbnZlbG9wZS5BdHRyaWJ1dGVzRW50cnkaMQoPQXR0cmlidXRlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEiPAoJRW50aXR5UmVmEgsKA3VybhgBIAEoCRITCgtlbnRpdHlfdHlwZRgCIAEoCRINCgVsYWJlbBgDIAEoCSLyAwoFQ2xhaW0SCgoCaWQYASABKAkSEwoLc3ViamVjdF91cm4YAiABKAkSKgoLc3ViamVjdF9yZWYYAyABKAsyFS5jZXJlYnJvLnYxLkVudGl0eVJlZhIRCglwcmVkaWNhdGUYBCABKAkSEgoKb2JqZWN0X3VybhgFIAEoCRIpCgpvYmplY3RfcmVmGAYgASgLMhUuY2VyZWJyby52MS5FbnRpdHlSZWYSFAoMb2JqZWN0X3ZhbHVlGAcgASgJEhIKCmNsYWltX3R5cGUYCCABKAkSDgoGc3RhdHVzGAkgASgJEhcKD3NvdXJjZV9ldmVudF9pZBgKIAEoCRIvCgtvYnNlcnZlZF9hdBgLIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLgoKdmFsaWRfZnJvbRgMIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLAoIdmFsaWRfdG8YDSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEjUKCmF0dHJpYnV0ZXMYDiADKAsyIS5jZXJlYnJvLnYxLkNsYWltLkF0dHJpYnV0ZXNFbnRyeRoxCg9BdHRyaWJ1dGVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgJOgI4AUJLWklnaXRodWIuY29tL3dyaXRlci9jZXJlYnJvL3Nkay9nby9jZXJlYnJvYXBpL2dlbnByb3RvL2NlcmVicm8vdjE7Y2VyZWJyb3YxYgZwcm90bzM", [file_google_protobuf_timestamp]); /** * @generated from message cerebro.v1.EventEnvelope diff --git a/proto/cerebro/v1/primitives.proto b/proto/cerebro/v1/primitives.proto index 09c65668..d6505125 100644 --- a/proto/cerebro/v1/primitives.proto +++ b/proto/cerebro/v1/primitives.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package cerebro.v1; -option go_package = "github.com/writer/aperio/gen/cerebro/v1;cerebrov1"; +option go_package = "github.com/writer/cerebro/sdk/go/cerebroapi/genproto/cerebro/v1;cerebrov1"; import "google/protobuf/timestamp.proto";