10 Commits

Author SHA1 Message Date
github-actions[bot]
976b655ff2 chore: auto-generate protobuf files [skip ci] 2026-04-03 10:09:51 +00:00
Дмитрий
641e2277d0 fix: dist build
All checks were successful
Publish / Publish Job (push) Successful in 2m37s
2026-04-03 13:07:10 +03:00
github-actions[bot]
44c1cfb80a chore: auto-generate protobuf files [skip ci] 2026-04-03 08:15:10 +00:00
Дмитрий
482ffdd386 add: add phone string ldap user data | v
All checks were successful
Publish / Publish Job (push) Successful in 2m37s
2026-04-03 11:12:12 +03:00
Дмитрий
0de3225481 add: add phone string ldap user data
Some checks failed
Publish / Publish Job (push) Has been cancelled
2026-04-03 11:11:49 +03:00
Дмитрий
8cbc2f86b3 fix: package name account -> account.v1 | change version
All checks were successful
Publish / Publish Job (push) Successful in 2m36s
2026-04-03 08:20:50 +03:00
github-actions[bot]
47e9aa47b9 chore: auto-generate protobuf files [skip ci] 2026-04-03 05:18:19 +00:00
Дмитрий
3a38e5f06c fix: package name account -> account.v1
Some checks failed
Publish / Publish Job (push) Failing after 2m37s
2026-04-03 08:15:37 +03:00
Дмитрий
97a6e14a77 add proto path link
All checks were successful
Publish / Publish Job (push) Successful in 2m41s
2026-04-02 21:05:21 +03:00
github-actions[bot]
e4b4a30664 chore: auto-generate protobuf files [skip ci] 2026-04-02 17:54:22 +00:00
11 changed files with 66 additions and 172 deletions

View File

@@ -9,12 +9,13 @@ import type { Metadata } from "@grpc/grpc-js";
import { GrpcMethod, GrpcStreamMethod } from "@nestjs/microservices";
import { Observable } from "rxjs";
export const protobufPackage = "account";
export const protobufPackage = "account.v1";
export enum Presence {
PRESENCE_UNSPECIFIED = 0,
OFFLINE = 1,
ONLINE = 2,
AWAY = 3,
UNRECOGNIZED = -1,
}
@@ -43,7 +44,7 @@ export interface GetAccountResponse {
hasPin: boolean;
}
export const ACCOUNT_PACKAGE_NAME = "account";
export const ACCOUNT_V1_PACKAGE_NAME = "account.v1";
export interface AccountServiceClient {
getAccount(request: GetAccountRequest, metadata?: Metadata): Observable<GetAccountResponse>;

View File

@@ -27,6 +27,7 @@ const (
Presence_PRESENCE_UNSPECIFIED Presence = 0
Presence_OFFLINE Presence = 1
Presence_ONLINE Presence = 2
Presence_AWAY Presence = 3
)
// Enum value maps for Presence.
@@ -35,11 +36,13 @@ var (
0: "PRESENCE_UNSPECIFIED",
1: "OFFLINE",
2: "ONLINE",
3: "AWAY",
}
Presence_value = map[string]int32{
"PRESENCE_UNSPECIFIED": 0,
"OFFLINE": 1,
"ONLINE": 2,
"AWAY": 3,
}
)
@@ -126,7 +129,7 @@ type GetAccountResponse struct {
Roles []string `protobuf:"bytes,8,rep,name=roles,proto3" json:"roles,omitempty"`
AvatarUrl string `protobuf:"bytes,9,opt,name=avatar_url,json=avatarUrl,proto3" json:"avatar_url,omitempty"`
EmployeeId *string `protobuf:"bytes,10,opt,name=employee_id,json=employeeId,proto3,oneof" json:"employee_id,omitempty"`
Presence Presence `protobuf:"varint,11,opt,name=presence,proto3,enum=account.Presence" json:"presence,omitempty"`
Presence Presence `protobuf:"varint,11,opt,name=presence,proto3,enum=account.v1.Presence" json:"presence,omitempty"`
LastActive string `protobuf:"bytes,12,opt,name=last_active,json=lastActive,proto3" json:"last_active,omitempty"`
CustomStatusText string `protobuf:"bytes,13,opt,name=custom_status_text,json=customStatusText,proto3" json:"custom_status_text,omitempty"`
CustomStatusEmoji string `protobuf:"bytes,14,opt,name=custom_status_emoji,json=customStatusEmoji,proto3" json:"custom_status_emoji,omitempty"`
@@ -298,9 +301,10 @@ var File_account_proto protoreflect.FileDescriptor
const file_account_proto_rawDesc = "" +
"\n" +
"\raccount.proto\x12\aaccount\"#\n" +
"\raccount.proto\x12\n" +
"account.v1\"#\n" +
"\x11GetAccountRequest\x12\x0e\n" +
"\x02id\x18\x01 \x01(\tR\x02id\"\xca\x04\n" +
"\x02id\x18\x01 \x01(\tR\x02id\"\xcd\x04\n" +
"\x12GetAccountResponse\x12\x0e\n" +
"\x02id\x18\x01 \x01(\tR\x02id\x12\x1a\n" +
"\busername\x18\x02 \x01(\tR\busername\x12\x14\n" +
@@ -314,8 +318,8 @@ const file_account_proto_rawDesc = "" +
"avatar_url\x18\t \x01(\tR\tavatarUrl\x12$\n" +
"\vemployee_id\x18\n" +
" \x01(\tH\x00R\n" +
"employeeId\x88\x01\x01\x12-\n" +
"\bpresence\x18\v \x01(\x0e2\x11.account.PresenceR\bpresence\x12\x1f\n" +
"employeeId\x88\x01\x01\x120\n" +
"\bpresence\x18\v \x01(\x0e2\x14.account.v1.PresenceR\bpresence\x12\x1f\n" +
"\vlast_active\x18\f \x01(\tR\n" +
"lastActive\x12,\n" +
"\x12custom_status_text\x18\r \x01(\tR\x10customStatusText\x12.\n" +
@@ -324,15 +328,16 @@ const file_account_proto_rawDesc = "" +
"\blanguage\x18\x10 \x01(\tR\blanguage\x12$\n" +
"\x0etwo_fa_enabled\x18\x11 \x01(\bR\ftwoFaEnabled\x12\x17\n" +
"\ahas_pin\x18\x12 \x01(\bR\x06hasPinB\x0e\n" +
"\f_employee_id*=\n" +
"\f_employee_id*G\n" +
"\bPresence\x12\x18\n" +
"\x14PRESENCE_UNSPECIFIED\x10\x00\x12\v\n" +
"\aOFFLINE\x10\x01\x12\n" +
"\n" +
"\x06ONLINE\x10\x022W\n" +
"\x0eAccountService\x12E\n" +
"\x06ONLINE\x10\x02\x12\b\n" +
"\x04AWAY\x10\x032]\n" +
"\x0eAccountService\x12K\n" +
"\n" +
"GetAccount\x12\x1a.account.GetAccountRequest\x1a\x1b.account.GetAccountResponseB*Z(git.lendry.ru/lendry-erp/proto.git/go;pbb\x06proto3"
"GetAccount\x12\x1d.account.v1.GetAccountRequest\x1a\x1e.account.v1.GetAccountResponseB*Z(git.lendry.ru/lendry-erp/proto.git/go;pbb\x06proto3"
var (
file_account_proto_rawDescOnce sync.Once
@@ -349,14 +354,14 @@ func file_account_proto_rawDescGZIP() []byte {
var file_account_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_account_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_account_proto_goTypes = []any{
(Presence)(0), // 0: account.Presence
(*GetAccountRequest)(nil), // 1: account.GetAccountRequest
(*GetAccountResponse)(nil), // 2: account.GetAccountResponse
(Presence)(0), // 0: account.v1.Presence
(*GetAccountRequest)(nil), // 1: account.v1.GetAccountRequest
(*GetAccountResponse)(nil), // 2: account.v1.GetAccountResponse
}
var file_account_proto_depIdxs = []int32{
0, // 0: account.GetAccountResponse.presence:type_name -> account.Presence
1, // 1: account.AccountService.GetAccount:input_type -> account.GetAccountRequest
2, // 2: account.AccountService.GetAccount:output_type -> account.GetAccountResponse
0, // 0: account.v1.GetAccountResponse.presence:type_name -> account.v1.Presence
1, // 1: account.v1.AccountService.GetAccount:input_type -> account.v1.GetAccountRequest
2, // 2: account.v1.AccountService.GetAccount:output_type -> account.v1.GetAccountResponse
2, // [2:3] is the sub-list for method output_type
1, // [1:2] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name

View File

@@ -19,7 +19,7 @@ import (
const _ = grpc.SupportPackageIsVersion9
const (
AccountService_GetAccount_FullMethodName = "/account.AccountService/GetAccount"
AccountService_GetAccount_FullMethodName = "/account.v1.AccountService/GetAccount"
)
// AccountServiceClient is the client API for AccountService service.
@@ -108,7 +108,7 @@ func _AccountService_GetAccount_Handler(srv interface{}, ctx context.Context, de
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var AccountService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "account.AccountService",
ServiceName: "account.v1.AccountService",
HandlerType: (*AccountServiceServer)(nil),
Methods: []grpc.MethodDesc{
{

View File

@@ -21,107 +21,6 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// Полная модель пользователя
type UserData struct {
state protoimpl.MessageState `protogen:"open.v1"`
Dn string `protobuf:"bytes,1,opt,name=dn,proto3" json:"dn,omitempty"` // Полный путь в AD (Distinguished Name)
Username string `protobuf:"bytes,2,opt,name=username,proto3" json:"username,omitempty"` // Логин (sAMAccountName)
DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` // ФИО (displayName)
Email string `protobuf:"bytes,4,opt,name=email,proto3" json:"email,omitempty"` // Почта (mail)
Description string `protobuf:"bytes,5,opt,name=description,proto3" json:"description,omitempty"` // Описание/Должность (description)
Avatar []byte `protobuf:"bytes,6,opt,name=avatar,proto3" json:"avatar,omitempty"` // Аватарка в байтах (thumbnailPhoto)
Groups []string `protobuf:"bytes,7,rep,name=groups,proto3" json:"groups,omitempty"` // Список групп
IsActive bool `protobuf:"varint,8,opt,name=is_active,json=isActive,proto3" json:"is_active,omitempty"` // Статус аккаунта
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *UserData) Reset() {
*x = UserData{}
mi := &file_ldap_auth_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *UserData) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UserData) ProtoMessage() {}
func (x *UserData) ProtoReflect() protoreflect.Message {
mi := &file_ldap_auth_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 UserData.ProtoReflect.Descriptor instead.
func (*UserData) Descriptor() ([]byte, []int) {
return file_ldap_auth_proto_rawDescGZIP(), []int{0}
}
func (x *UserData) GetDn() string {
if x != nil {
return x.Dn
}
return ""
}
func (x *UserData) GetUsername() string {
if x != nil {
return x.Username
}
return ""
}
func (x *UserData) GetDisplayName() string {
if x != nil {
return x.DisplayName
}
return ""
}
func (x *UserData) GetEmail() string {
if x != nil {
return x.Email
}
return ""
}
func (x *UserData) GetDescription() string {
if x != nil {
return x.Description
}
return ""
}
func (x *UserData) GetAvatar() []byte {
if x != nil {
return x.Avatar
}
return nil
}
func (x *UserData) GetGroups() []string {
if x != nil {
return x.Groups
}
return nil
}
func (x *UserData) GetIsActive() bool {
if x != nil {
return x.IsActive
}
return false
}
// --- Авторизация ---
type VerifyRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
@@ -133,7 +32,7 @@ type VerifyRequest struct {
func (x *VerifyRequest) Reset() {
*x = VerifyRequest{}
mi := &file_ldap_auth_proto_msgTypes[1]
mi := &file_ldap_auth_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -145,7 +44,7 @@ func (x *VerifyRequest) String() string {
func (*VerifyRequest) ProtoMessage() {}
func (x *VerifyRequest) ProtoReflect() protoreflect.Message {
mi := &file_ldap_auth_proto_msgTypes[1]
mi := &file_ldap_auth_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -158,7 +57,7 @@ func (x *VerifyRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use VerifyRequest.ProtoReflect.Descriptor instead.
func (*VerifyRequest) Descriptor() ([]byte, []int) {
return file_ldap_auth_proto_rawDescGZIP(), []int{1}
return file_ldap_auth_proto_rawDescGZIP(), []int{0}
}
func (x *VerifyRequest) GetUsername() string {
@@ -186,7 +85,7 @@ type VerifyResponse struct {
func (x *VerifyResponse) Reset() {
*x = VerifyResponse{}
mi := &file_ldap_auth_proto_msgTypes[2]
mi := &file_ldap_auth_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -198,7 +97,7 @@ func (x *VerifyResponse) String() string {
func (*VerifyResponse) ProtoMessage() {}
func (x *VerifyResponse) ProtoReflect() protoreflect.Message {
mi := &file_ldap_auth_proto_msgTypes[2]
mi := &file_ldap_auth_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -211,7 +110,7 @@ func (x *VerifyResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use VerifyResponse.ProtoReflect.Descriptor instead.
func (*VerifyResponse) Descriptor() ([]byte, []int) {
return file_ldap_auth_proto_rawDescGZIP(), []int{2}
return file_ldap_auth_proto_rawDescGZIP(), []int{1}
}
func (x *VerifyResponse) GetSuccess() bool {
@@ -239,23 +138,15 @@ var File_ldap_auth_proto protoreflect.FileDescriptor
const file_ldap_auth_proto_rawDesc = "" +
"\n" +
"\x0fldap-auth.proto\x12\fldap_auth.v1\"\xde\x01\n" +
"\bUserData\x12\x0e\n" +
"\x02dn\x18\x01 \x01(\tR\x02dn\x12\x1a\n" +
"\busername\x18\x02 \x01(\tR\busername\x12!\n" +
"\fdisplay_name\x18\x03 \x01(\tR\vdisplayName\x12\x14\n" +
"\x05email\x18\x04 \x01(\tR\x05email\x12 \n" +
"\vdescription\x18\x05 \x01(\tR\vdescription\x12\x16\n" +
"\x06avatar\x18\x06 \x01(\fR\x06avatar\x12\x16\n" +
"\x06groups\x18\a \x03(\tR\x06groups\x12\x1b\n" +
"\tis_active\x18\b \x01(\bR\bisActive\"G\n" +
"\x0fldap-auth.proto\x12\fldap_auth.v1\x1a\n" +
"ldap.proto\"G\n" +
"\rVerifyRequest\x12\x1a\n" +
"\busername\x18\x01 \x01(\tR\busername\x12\x1a\n" +
"\bpassword\x18\x02 \x01(\tR\bpassword\"{\n" +
"\bpassword\x18\x02 \x01(\tR\bpassword\"v\n" +
"\x0eVerifyResponse\x12\x18\n" +
"\asuccess\x18\x01 \x01(\bR\asuccess\x12#\n" +
"\rerror_message\x18\x02 \x01(\tR\ferrorMessage\x12*\n" +
"\x04user\x18\x03 \x01(\v2\x16.ldap_auth.v1.UserDataR\x04user2Z\n" +
"\rerror_message\x18\x02 \x01(\tR\ferrorMessage\x12%\n" +
"\x04user\x18\x03 \x01(\v2\x11.ldap.v1.UserDataR\x04user2Z\n" +
"\x0fLdapAuthService\x12G\n" +
"\n" +
"VerifyUser\x12\x1b.ldap_auth.v1.VerifyRequest\x1a\x1c.ldap_auth.v1.VerifyResponseB*Z(git.lendry.ru/lendry-erp/proto.git/go;pbb\x06proto3"
@@ -272,16 +163,16 @@ func file_ldap_auth_proto_rawDescGZIP() []byte {
return file_ldap_auth_proto_rawDescData
}
var file_ldap_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_ldap_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_ldap_auth_proto_goTypes = []any{
(*UserData)(nil), // 0: ldap_auth.v1.UserData
(*VerifyRequest)(nil), // 1: ldap_auth.v1.VerifyRequest
(*VerifyResponse)(nil), // 2: ldap_auth.v1.VerifyResponse
(*VerifyRequest)(nil), // 0: ldap_auth.v1.VerifyRequest
(*VerifyResponse)(nil), // 1: ldap_auth.v1.VerifyResponse
(*UserData)(nil), // 2: ldap.v1.UserData
}
var file_ldap_auth_proto_depIdxs = []int32{
0, // 0: ldap_auth.v1.VerifyResponse.user:type_name -> ldap_auth.v1.UserData
1, // 1: ldap_auth.v1.LdapAuthService.VerifyUser:input_type -> ldap_auth.v1.VerifyRequest
2, // 2: ldap_auth.v1.LdapAuthService.VerifyUser:output_type -> ldap_auth.v1.VerifyResponse
2, // 0: ldap_auth.v1.VerifyResponse.user:type_name -> ldap.v1.UserData
0, // 1: ldap_auth.v1.LdapAuthService.VerifyUser:input_type -> ldap_auth.v1.VerifyRequest
1, // 2: ldap_auth.v1.LdapAuthService.VerifyUser:output_type -> ldap_auth.v1.VerifyResponse
2, // [2:3] is the sub-list for method output_type
1, // [1:2] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
@@ -294,13 +185,14 @@ func file_ldap_auth_proto_init() {
if File_ldap_auth_proto != nil {
return
}
file_ldap_proto_init()
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_ldap_auth_proto_rawDesc), len(file_ldap_auth_proto_rawDesc)),
NumEnums: 0,
NumMessages: 3,
NumMessages: 2,
NumExtensions: 0,
NumServices: 1,
},

View File

@@ -124,6 +124,7 @@ type UserData struct {
Avatar []byte `protobuf:"bytes,6,opt,name=avatar,proto3" json:"avatar,omitempty"` // Аватарка в байтах (thumbnailPhoto)
Groups []string `protobuf:"bytes,7,rep,name=groups,proto3" json:"groups,omitempty"` // Список групп
IsActive bool `protobuf:"varint,8,opt,name=is_active,json=isActive,proto3" json:"is_active,omitempty"` // Статус аккаунта
Phone string `protobuf:"bytes,9,opt,name=phone,proto3" json:"phone,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -214,6 +215,13 @@ func (x *UserData) GetIsActive() bool {
return false
}
func (x *UserData) GetPhone() string {
if x != nil {
return x.Phone
}
return ""
}
// Модель группы
type GroupData struct {
state protoimpl.MessageState `protogen:"open.v1"`
@@ -700,7 +708,7 @@ const file_ldap_proto_rawDesc = "" +
"\fEmptyRequest\"O\n" +
"\x0eStatusResponse\x12\x18\n" +
"\asuccess\x18\x01 \x01(\bR\asuccess\x12#\n" +
"\rerror_message\x18\x02 \x01(\tR\ferrorMessage\"\xde\x01\n" +
"\rerror_message\x18\x02 \x01(\tR\ferrorMessage\"\xf4\x01\n" +
"\bUserData\x12\x0e\n" +
"\x02dn\x18\x01 \x01(\tR\x02dn\x12\x1a\n" +
"\busername\x18\x02 \x01(\tR\busername\x12!\n" +
@@ -709,7 +717,8 @@ const file_ldap_proto_rawDesc = "" +
"\vdescription\x18\x05 \x01(\tR\vdescription\x12\x16\n" +
"\x06avatar\x18\x06 \x01(\fR\x06avatar\x12\x16\n" +
"\x06groups\x18\a \x03(\tR\x06groups\x12\x1b\n" +
"\tis_active\x18\b \x01(\bR\bisActive\"/\n" +
"\tis_active\x18\b \x01(\bR\bisActive\x12\x14\n" +
"\x05phone\x18\t \x01(\tR\x05phone\"/\n" +
"\tGroupData\x12\x0e\n" +
"\x02dn\x18\x01 \x01(\tR\x02dn\x12\x12\n" +
"\x04name\x18\x02 \x01(\tR\x04name\"z\n" +

View File

@@ -8,29 +8,10 @@
import type { Metadata } from "@grpc/grpc-js";
import { GrpcMethod, GrpcStreamMethod } from "@nestjs/microservices";
import { Observable } from "rxjs";
import { UserData } from "./ldap";
export const protobufPackage = "ldap_auth.v1";
/** Полная модель пользователя */
export interface UserData {
/** Полный путь в AD (Distinguished Name) */
dn: string;
/** Логин (sAMAccountName) */
username: string;
/** ФИО (displayName) */
displayName: string;
/** Почта (mail) */
email: string;
/** Описание/Должность (description) */
description: string;
/** Аватарка в байтах (thumbnailPhoto) */
avatar: Uint8Array;
/** Список групп */
groups: string[];
/** Статус аккаунта */
isActive: boolean;
}
/** --- Авторизация --- */
export interface VerifyRequest {
username: string;

View File

@@ -43,6 +43,7 @@ export interface UserData {
groups: string[];
/** Статус аккаунта */
isActive: boolean;
phone: string;
}
/** Модель группы */

View File

@@ -1,6 +1,6 @@
{
"name": "@lendry-erp/contracts",
"version": "1.0.30",
"version": "1.0.35",
"description": "Protobuf definitions and generated TypeScript types",
"type": "commonjs",
"main": "./dist/index.js",

View File

@@ -1,6 +1,6 @@
syntax = "proto3";
package account;
package account.v1;
option go_package = "git.lendry.ru/lendry-erp/proto.git/go;pb";
@@ -37,5 +37,6 @@ enum Presence {
PRESENCE_UNSPECIFIED = 0;
OFFLINE = 1;
ONLINE = 2;
AWAY = 3;
}

View File

@@ -39,6 +39,7 @@ message UserData {
bytes avatar = 6; // Аватарка в байтах (thumbnailPhoto)
repeated string groups = 7; // Список групп
bool is_active = 8; // Статус аккаунта
string phone = 9;
}
// Модель группы

View File

@@ -1,6 +1,9 @@
import { join } from "path";
export const PROTO_PATHS = {
AUTH: join(__dirname, "../../proto/identity.proto"),
AUTH: join(__dirname, "../../proto/auth.proto"),
LDAP_AUTH: join(__dirname, "../../proto/ldap-auth.proto"),
ACCOUNT: join(__dirname, "../../proto/account.proto"),
TWOFA: join(__dirname, "../../proto/twofa.proto"),
LDAP: join(__dirname, "../../proto/ldap.proto"),
} as const;