@ticket_for_cinema/contracts 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/gen/auth.ts ADDED
@@ -0,0 +1,50 @@
1
+ // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
2
+ // versions:
3
+ // protoc-gen-ts_proto v1.181.2
4
+ // protoc v3.21.12
5
+ // source: auth.proto
6
+
7
+ /* eslint-disable */
8
+ import { GrpcMethod, GrpcStreamMethod } from "@nestjs/microservices";
9
+ import { Observable } from "rxjs";
10
+
11
+ export const protobufPackage = "auth.v1";
12
+
13
+ /** указываем версию протобуфера */
14
+
15
+ export interface SendOtpRequest {
16
+ /** менять номер нельзя, чтоб не было рассинхронизации данных */
17
+ identifier: string;
18
+ type: string;
19
+ }
20
+
21
+ export interface SendOtpResponse {
22
+ ok: boolean;
23
+ }
24
+
25
+ export const AUTH_V1_PACKAGE_NAME = "auth.v1";
26
+
27
+ export interface AuthServiceClient {
28
+ sendOtp(request: SendOtpRequest): Observable<SendOtpResponse>;
29
+ }
30
+
31
+ export interface AuthServiceController {
32
+ sendOtp(request: SendOtpRequest): Promise<SendOtpResponse> | Observable<SendOtpResponse> | SendOtpResponse;
33
+ }
34
+
35
+ export function AuthServiceControllerMethods() {
36
+ return function (constructor: Function) {
37
+ const grpcMethods: string[] = ["sendOtp"];
38
+ for (const method of grpcMethods) {
39
+ const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
40
+ GrpcMethod("AuthService", method)(constructor.prototype[method], method, descriptor);
41
+ }
42
+ const grpcStreamMethods: string[] = [];
43
+ for (const method of grpcStreamMethods) {
44
+ const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
45
+ GrpcStreamMethod("AuthService", method)(constructor.prototype[method], method, descriptor);
46
+ }
47
+ };
48
+ }
49
+
50
+ export const AUTH_SERVICE_NAME = "AuthService";
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@ticket_for_cinema/contracts",
3
+ "version": "1.0.0",
4
+ "description": "Contracts for microservices",
5
+ "scripts": {
6
+ "generate": "protoc -I ./proto ./proto/*.proto --ts_proto_out=./gen --ts_proto_opt=nestJs=true,package=omit"
7
+ },
8
+ "files": [
9
+ "proto",
10
+ "gen"
11
+ ],
12
+ "dependencies": {
13
+ "@nestjs/microservices": "^11.1.11",
14
+ "rxjs": "^7.8.2"
15
+ },
16
+ "devDependencies": {
17
+ "ts-proto": "^1.176.0"
18
+ },
19
+ "publishConfig": {
20
+ "access": "public"
21
+ }
22
+ }
@@ -0,0 +1,17 @@
1
+ syntax = "proto3"; // указываем версию протобуфера
2
+
3
+ package auth.v1; // указываем пакет тут указываем доменную область
4
+
5
+ service AuthService {
6
+ rpc SendOtp (SendOtpRequest) returns (SendOtpResponse);
7
+
8
+ }
9
+
10
+ message SendOtpRequest {
11
+ string identifier = 1; // менять номер нельзя, чтоб не было рассинхронизации данных
12
+ string type = 2;
13
+ }
14
+
15
+ message SendOtpResponse {
16
+ bool ok = 1;
17
+ }
package/proto/redme.md ADDED
@@ -0,0 +1,521 @@
1
+ # Конспект по Protocol Buffers (proto файлам) для gRPC
2
+
3
+ ## Что такое .proto файл?
4
+
5
+ `.proto` файл - это файл описания данных и сервисов для gRPC. Он определяет:
6
+
7
+ - **Структуру сообщений** (какие данные передаются)
8
+ - **Сервисы и методы** (какие операции можно выполнять)
9
+ - **Типы данных** (какие типы полей используются)
10
+
11
+ Из `.proto` файла генерируется код на разных языках программирования (TypeScript, Go, Python и т.д.)
12
+
13
+ ---
14
+
15
+ ## Базовая структура .proto файла
16
+
17
+ ```protobuf
18
+ syntax = "proto3"; // Версия Protocol Buffers (всегда используй proto3)
19
+
20
+ package auth.v1; // Пакет - организация кода (как namespace)
21
+
22
+ // Сообщение (структура данных)
23
+ message SendOtpRequest {
24
+ string identifier = 1; // Поле: тип название = номер
25
+ string type = 2;
26
+ }
27
+
28
+ // Сервис (набор методов)
29
+ service AuthService {
30
+ rpc SendOtp(SendOtpRequest) returns (SendOtpResponse); // Метод
31
+ }
32
+ ```
33
+
34
+ ---
35
+
36
+ ## 1. Синтаксис и пакет
37
+
38
+ ### `syntax = "proto3"`
39
+
40
+ - Указывает версию Protocol Buffers
41
+ - Всегда используй `proto3` (самая новая версия)
42
+
43
+ ### `package auth.v1`
44
+
45
+ - Организует код в пространство имен
46
+ - Помогает избежать конфликтов имен
47
+ - Формат: `название.версия` (например, `auth.v1`, `user.v2`)
48
+
49
+ ---
50
+
51
+ ## 2. Сообщения (Messages)
52
+
53
+ Сообщения - это структуры данных (как классы или интерфейсы)
54
+
55
+ ```protobuf
56
+ message User {
57
+ string name = 1; // Поле 1: имя пользователя
58
+ int32 age = 2; // Поле 2: возраст
59
+ bool is_active = 3; // Поле 3: активен ли
60
+ }
61
+ ```
62
+
63
+ ### Важно про номера полей:
64
+
65
+ - Каждое поле имеет **уникальный номер** (1, 2, 3...)
66
+ - Номера **нельзя менять** после релиза (иначе сломается совместимость)
67
+ - Номера 1-15 занимают 1 байт (используй для частых полей)
68
+ - Номера 16-2047 занимают 2 байта
69
+
70
+ ---
71
+
72
+ ## 3. Типы данных
73
+
74
+ ### Скалярные типы (простые):
75
+
76
+ | Proto тип | Описание | Пример |
77
+ | --------- | --------------------------------- | ---------------- |
78
+ | `string` | Строка | `"Привет"` |
79
+ | `int32` | Целое число 32-бит | `42` |
80
+ | `int64` | Целое число 64-бит | `1234567890` |
81
+ | `uint32` | Беззнаковое целое 32-бит | `100` |
82
+ | `uint64` | Беззнаковое целое 64-бит | `9999` |
83
+ | `bool` | Булево значение | `true` / `false` |
84
+ | `float` | Число с плавающей точкой | `3.14` |
85
+ | `double` | Число с плавающей точкой (точнее) | `3.14159265` |
86
+ | `bytes` | Бинарные данные | `[0x01, 0x02]` |
87
+
88
+ ### Пример:
89
+
90
+ ```protobuf
91
+ message Product {
92
+ string name = 1; // "iPhone"
93
+ double price = 2; // 999.99
94
+ int32 quantity = 3; // 10
95
+ bool in_stock = 4; // true
96
+ bytes image = 5; // бинарные данные картинки
97
+ }
98
+ ```
99
+
100
+ ---
101
+
102
+ ## 4. Повторяющиеся поля (массивы)
103
+
104
+ Используй `repeated` для массивов:
105
+
106
+ ```protobuf
107
+ message ShoppingCart {
108
+ repeated string items = 1; // Массив строк: ["яблоко", "банан"]
109
+ repeated int32 quantities = 2; // Массив чисел: [5, 3]
110
+ }
111
+ ```
112
+
113
+ ---
114
+
115
+ ## 5. Вложенные сообщения
116
+
117
+ Можно использовать одно сообщение внутри другого:
118
+
119
+ ```protobuf
120
+ message Address {
121
+ string city = 1;
122
+ string street = 2;
123
+ }
124
+
125
+ message User {
126
+ string name = 1;
127
+ Address address = 2; // Вложенное сообщение
128
+ }
129
+ ```
130
+
131
+ ---
132
+
133
+ ## 6. Enum (перечисления)
134
+
135
+ Для фиксированного набора значений:
136
+
137
+ ```protobuf
138
+ enum Status {
139
+ STATUS_UNSPECIFIED = 0; // Всегда начинай с 0 и _UNSPECIFIED
140
+ STATUS_PENDING = 1;
141
+ STATUS_APPROVED = 2;
142
+ STATUS_REJECTED = 3;
143
+ }
144
+
145
+ message Order {
146
+ string id = 1;
147
+ Status status = 2; // Использование enum
148
+ }
149
+ ```
150
+
151
+ **Важно:** Первое значение enum всегда должно быть `0` и называться `НАЗВАНИЕ_UNSPECIFIED`
152
+
153
+ ---
154
+
155
+ ## 7. Опциональные поля
156
+
157
+ В proto3 все поля опциональны по умолчанию. Если поле не задано, оно имеет значение по умолчанию:
158
+
159
+ - `string` → `""`
160
+ - `int32` → `0`
161
+ - `bool` → `false`
162
+
163
+ Если нужно явно указать, что поле опционально:
164
+
165
+ ```protobuf
166
+ message User {
167
+ string name = 1;
168
+ optional string nickname = 2; // Может быть null
169
+ }
170
+ ```
171
+
172
+ ---
173
+
174
+ ## 8. Сервисы (Services)
175
+
176
+ Сервис - это набор RPC методов (удаленных вызовов)
177
+
178
+ ```protobuf
179
+ service UserService {
180
+ // Простой вызов: один запрос → один ответ
181
+ rpc GetUser(GetUserRequest) returns (GetUserResponse);
182
+
183
+ // Server streaming: один запрос → много ответов
184
+ rpc ListUsers(ListUsersRequest) returns (stream User);
185
+
186
+ // Client streaming: много запросов → один ответ
187
+ rpc CreateUsers(stream CreateUserRequest) returns (CreateUsersResponse);
188
+
189
+ // Bidirectional streaming: много запросов ↔ много ответов
190
+ rpc Chat(stream ChatMessage) returns (stream ChatMessage);
191
+ }
192
+ ```
193
+
194
+ ### Типы методов:
195
+
196
+ 1. **Unary (обычный)** - один запрос, один ответ
197
+
198
+ ```protobuf
199
+ rpc SendOtp(SendOtpRequest) returns (SendOtpResponse);
200
+ ```
201
+
202
+ 2. **Server streaming** - один запрос, много ответов (стрим)
203
+
204
+ ```protobuf
205
+ rpc WatchOrders(WatchRequest) returns (stream Order);
206
+ ```
207
+
208
+ 3. **Client streaming** - много запросов (стрим), один ответ
209
+
210
+ ```protobuf
211
+ rpc UploadFile(stream FileChunk) returns (UploadResponse);
212
+ ```
213
+
214
+ 4. **Bidirectional streaming** - стрим в обе стороны
215
+ ```protobuf
216
+ rpc Chat(stream Message) returns (stream Message);
217
+ ```
218
+
219
+ ---
220
+
221
+ ## 9. Импорты
222
+
223
+ Можно импортировать другие .proto файлы:
224
+
225
+ ```protobuf
226
+ import "google/protobuf/timestamp.proto";
227
+ import "common/types.proto";
228
+
229
+ message Post {
230
+ string title = 1;
231
+ google.protobuf.Timestamp created_at = 2; // Использование импортированного типа
232
+ }
233
+ ```
234
+
235
+ ---
236
+
237
+ ## 10. Комментарии
238
+
239
+ ```protobuf
240
+ // Однострочный комментарий
241
+
242
+ /*
243
+ Многострочный
244
+ комментарий
245
+ */
246
+
247
+ message User {
248
+ string name = 1; // Комментарий к полю
249
+ }
250
+ ```
251
+
252
+ ---
253
+
254
+ ## 11. Полный пример .proto файла
255
+
256
+ ```protobuf
257
+ syntax = "proto3";
258
+
259
+ package shop.v1;
260
+
261
+ import "google/protobuf/timestamp.proto";
262
+ import "google/protobuf/duration.proto";
263
+ import "google/protobuf/struct.proto";
264
+ import "google/protobuf/empty.proto";
265
+ import "google/protobuf/any.proto";
266
+
267
+ // Перечисление статусов заказа
268
+ enum OrderStatus {
269
+ ORDER_STATUS_UNSPECIFIED = 0;
270
+ ORDER_STATUS_PENDING = 1;
271
+ ORDER_STATUS_PAID = 2;
272
+ ORDER_STATUS_SHIPPED = 3;
273
+ ORDER_STATUS_DELIVERED = 4;
274
+ }
275
+
276
+ // Сообщение: товар
277
+ message Product {
278
+ string id = 1;
279
+ string name = 2;
280
+ double price = 3;
281
+ int32 stock = 4;
282
+ google.protobuf.Timestamp created_at = 5; // время создания, но перед этим импортировать google.protobuf.Timestamp
283
+ google.protobuf.Duration duration = 6; // длительность, но перед этим импортировать google.protobuf.Duration
284
+ google.protobuf.Struct metadata = 7; // метаданные (структура json внутри протобуфера), но перед этим импортировать google.protobuf.Struct
285
+ }
286
+
287
+ // Сообщение: заказ
288
+ message Order {
289
+ string id = 1;
290
+ string user_id = 2;
291
+ repeated Product products = 3; // Массив товаров
292
+ OrderStatus status = 4; // Статус из enum
293
+ double total_price = 5;
294
+ }
295
+
296
+ // Запрос на создание заказа
297
+ message CreateOrderRequest {
298
+ string user_id = 1;
299
+ repeated string product_ids = 2;
300
+ }
301
+
302
+ // Ответ на создание заказа
303
+ message CreateOrderResponse {
304
+ Order order = 1;
305
+ bool success = 2;
306
+ string message = 3;
307
+ }
308
+
309
+ // Сервис для работы с заказами
310
+ service OrderService {
311
+ // Создать заказ
312
+ rpc CreateOrder(CreateOrderRequest) returns (CreateOrderResponse);
313
+
314
+ // Получить заказ по ID
315
+ rpc GetOrder(GetOrderRequest) returns (Order);
316
+
317
+ // Получить список всех заказов (стрим)
318
+ rpc ListOrders(ListOrdersRequest) returns (stream Order);
319
+ }
320
+ ```
321
+
322
+ ---
323
+
324
+ ## 12. Лучшие практики
325
+
326
+ ### ✅ Делай так:
327
+
328
+ - Всегда используй `syntax = "proto3"`
329
+ - Называй пакеты в формате `название.v1`, `название.v2`
330
+ - Первое значение enum всегда `0` и `_UNSPECIFIED`
331
+ - Используй `snake_case` для полей: `user_name`, `created_at`
332
+ - Используй `PascalCase` для сообщений: `UserProfile`, `CreateOrderRequest`
333
+ - Добавляй комментарии к сложным полям
334
+
335
+ ### ❌ Не делай так:
336
+
337
+ - Не меняй номера полей после релиза
338
+ - Не удаляй поля (помечай как `reserved` если нужно)
339
+ - Не используй `required` (в proto3 его нет)
340
+ - Не используй одинаковые номера для разных полей
341
+
342
+ ---
343
+
344
+ ## 13. Зарезервированные поля
345
+
346
+ Если нужно удалить поле, но сохранить его номер:
347
+
348
+ ```protobuf
349
+ message User {
350
+ reserved 2, 5 to 10; // Зарезервированные номера
351
+ reserved "old_field", "deleted"; // Зарезервированные имена
352
+
353
+ string name = 1;
354
+ int32 age = 3;
355
+ // Поле 2 удалено, но номер зарезервирован
356
+ }
357
+ ```
358
+
359
+ ---
360
+
361
+ ## 14. Как использовать .proto файлы
362
+
363
+ 1. **Создай .proto файл** с описанием данных и сервисов
364
+ 2. **Сгенерируй код** с помощью компилятора `protoc`:
365
+ ```bash
366
+ protoc --go_out=. --go-grpc_out=. auth.proto
367
+ ```
368
+ 3. **Используй сгенерированный код** в своем приложении
369
+
370
+ ---
371
+
372
+ ## Резюме
373
+
374
+ - `.proto` файл описывает структуру данных и API для gRPC
375
+ - **Messages** - структуры данных (как классы)
376
+ - **Services** - наборы методов (API)
377
+ - **Типы данных**: `string`, `int32`, `bool`, `repeated` и др.
378
+ - **Enum** - перечисления фиксированных значений
379
+ - **Номера полей** - уникальные и неизменяемые
380
+ - **4 типа RPC**: unary, server streaming, client streaming, bidirectional
381
+
382
+ ---
383
+
384
+ ## 15. Команда генерации TypeScript кода
385
+
386
+ ### Команда:
387
+
388
+ ```bash
389
+ protoc -I ./proto ./proto/*.proto --ts_proto_out=./gen --ts_proto_opt=nestJs=true,package=omit
390
+ ```
391
+
392
+ ### Разбор команды по частям:
393
+
394
+ | Параметр | Описание | Пример |
395
+ | ---------------------- | ---------------------------------- | --------------------------------- |
396
+ | `protoc` | Компилятор Protocol Buffers | Основная программа |
397
+ | `-I ./proto` | Папка с .proto файлами (include) | Ищет файлы в папке `./proto` |
398
+ | `./proto/*.proto` | Все .proto файлы для обработки | `auth.proto`, `user.proto` и т.д. |
399
+ | `--ts_proto_out=./gen` | Выходная папка для TypeScript кода | Генерирует файлы в папке `./gen` |
400
+ | `--ts_proto_opt=...` | Опции генерации | Настройки формата кода |
401
+
402
+ ### Опции генерации:
403
+
404
+ | Опция | Что делает | Пример |
405
+ | -------------- | ----------------------------------- | -------------------------------------------------- |
406
+ | `nestJs=true` | Генерирует код совместимый с NestJS | Декораторы `@GrpcMethod()` |
407
+ | `package=omit` | Пропускает префикс пакета в именах | Вместо `auth.v1.SendOtpRequest` → `SendOtpRequest` |
408
+
409
+ ### Что генерируется:
410
+
411
+ Из файла `auth.proto`:
412
+
413
+ ```protobuf
414
+ service AuthService {
415
+ rpc SendOtp (SendOtpRequest) returns (SendOtpResponse);
416
+ }
417
+
418
+ message SendOtpRequest {
419
+ string identifier = 1;
420
+ string type = 2;
421
+ }
422
+
423
+ message SendOtpResponse {
424
+ bool ok = 1;
425
+ }
426
+ ```
427
+
428
+ Генерируется `gen/auth.ts`:
429
+
430
+ ```typescript
431
+ // Интерфейсы для сообщений
432
+ export interface SendOtpRequest {
433
+ identifier: string;
434
+ type: string;
435
+ }
436
+
437
+ export interface SendOtpResponse {
438
+ ok: boolean;
439
+ }
440
+
441
+ // Клиент и контроллер для NestJS
442
+ export interface AuthServiceClient {
443
+ sendOtp(request: SendOtpRequest): Observable<SendOtpResponse>;
444
+ }
445
+
446
+ export interface AuthServiceController {
447
+ sendOtp(
448
+ request: SendOtpRequest
449
+ ): Promise<SendOtpResponse> | Observable<SendOtpResponse> | SendOtpResponse;
450
+ }
451
+ ```
452
+
453
+ ### Пример использования в NestJS:
454
+
455
+ **Контроллер:**
456
+
457
+ ```typescript
458
+ @Controller()
459
+ export class AuthController implements AuthServiceController {
460
+ @GrpcMethod("SendOtp")
461
+ async sendOtp(request: SendOtpRequest): Promise<SendOtpResponse> {
462
+ return { ok: true };
463
+ }
464
+ }
465
+ ```
466
+
467
+ **Клиент:**
468
+
469
+ ```typescript
470
+ @Injectable()
471
+ export class AuthClient {
472
+ constructor(@Inject("AUTH_SERVICE") private client: ClientGrpc) {}
473
+
474
+ sendOtp(request: SendOtpRequest): Observable<SendOtpResponse> {
475
+ return this.client
476
+ .getService<AuthServiceClient>("AuthService")
477
+ .sendOtp(request);
478
+ }
479
+ }
480
+ ```
481
+
482
+ ---
483
+
484
+ ## 16. Установка необходимых инструментов
485
+
486
+ ### 1. Protocol Buffers компилятор:
487
+
488
+ ```bash
489
+ # Установить protoc (добавить в PATH)
490
+ # Скачать с: https://github.com/protocolbuffers/protobuf/releases
491
+ # Или через пакетный менеджер
492
+ ```
493
+
494
+ ### 2. TypeScript плагин:
495
+
496
+ ```bash
497
+ npm install -g ts-proto
498
+ # или локально
499
+ npm install -D ts-proto
500
+ ```
501
+
502
+ ### 3. Проверка установки:
503
+
504
+ ```bash
505
+ protoc --version # Проверка protoc
506
+ protoc-gen-ts_proto --version # Проверка плагина
507
+ ```
508
+
509
+ ---
510
+
511
+ ## 17. Полный процесс работы с .proto файлами
512
+
513
+ 1. **Создать .proto файл** с описанием сервисов и сообщений
514
+ 2. **Установить инструменты** (`protoc` и `ts-proto`)
515
+ 3. **Сгенерировать TypeScript код** с помощью команды
516
+ 4. **Использовать сгенерированные интерфейсы** в NestJS приложении
517
+ 5. **Реализовать контроллеры** и клиенты на основе сгенерированного кода
518
+
519
+ ---
520
+
521
+ Это основа для работы с gRPC! 🚀