@databricks/zerobus-ingest-sdk 0.0.1 → 0.1.1

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.
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Utility functions for working with Protocol Buffer descriptors.
3
+ *
4
+ * These utilities help extract message descriptors from FileDescriptorSets
5
+ * generated by protoc, providing flexibility in choosing which message to use.
6
+ */
7
+
8
+ import * as fs from 'fs';
9
+ import * as protobuf from 'protobufjs';
10
+ import descriptor from 'protobufjs/ext/descriptor';
11
+
12
+ /**
13
+ * Options for loading a descriptor from a FileDescriptorSet.
14
+ */
15
+ export interface LoadDescriptorOptions {
16
+ /**
17
+ * Path to the descriptor file generated by protoc.
18
+ * Example: 'schemas/my_schema_descriptor.pb'
19
+ */
20
+ descriptorPath: string;
21
+
22
+ /**
23
+ * Name of the proto file within the FileDescriptorSet.
24
+ * This should match the filename in your .proto file.
25
+ * Example: 'schemas/air_quality.proto' or 'air_quality.proto'
26
+ */
27
+ protoFileName: string;
28
+
29
+ /**
30
+ * Name of the message type to extract.
31
+ * Example: 'AirQuality'
32
+ */
33
+ messageName: string;
34
+ }
35
+
36
+ /**
37
+ * Loads a specific message's DescriptorProto from a FileDescriptorSet.
38
+ *
39
+ * This function:
40
+ * 1. Reads the binary FileDescriptorSet file generated by protoc
41
+ * 2. Parses it using protobufjs
42
+ * 3. Finds the specified proto file and message within the FileDescriptorSet
43
+ * 4. Extracts just that message's DescriptorProto
44
+ * 5. Encodes it to base64 for use with the Zerobus SDK
45
+ *
46
+ * @param options - Configuration specifying which message to extract
47
+ * @returns Base64-encoded DescriptorProto string for the specified message
48
+ * @throws Error if the descriptor file, proto file, or message cannot be found
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * import { loadDescriptorProto } from '@databricks/zerobus-sdk/utils/descriptor';
53
+ *
54
+ * const descriptorBase64 = loadDescriptorProto({
55
+ * descriptorPath: 'schemas/air_quality_descriptor.pb',
56
+ * protoFileName: 'air_quality.proto',
57
+ * messageName: 'AirQuality'
58
+ * });
59
+ *
60
+ * const tableProperties = {
61
+ * tableName: 'catalog.schema.table',
62
+ * descriptorProto: descriptorBase64
63
+ * };
64
+ * ```
65
+ */
66
+ export function loadDescriptorProto(options: LoadDescriptorOptions): string {
67
+ const { descriptorPath, protoFileName, messageName } = options;
68
+
69
+ // Read the binary descriptor file
70
+ const descriptorBytes = fs.readFileSync(descriptorPath);
71
+
72
+ // Parse as FileDescriptorSet using the descriptor extension
73
+ const fileDescriptorSet = descriptor.FileDescriptorSet.decode(descriptorBytes) as any;
74
+
75
+ // Find the file descriptor matching the proto file name
76
+ const fileDescriptor = fileDescriptorSet.file.find((f: any) =>
77
+ f.name === protoFileName || f.name.endsWith('/' + protoFileName) || f.name.endsWith(protoFileName)
78
+ );
79
+
80
+ if (!fileDescriptor) {
81
+ throw new Error(
82
+ `Proto file '${protoFileName}' not found in descriptor. Available files: ${
83
+ fileDescriptorSet.file.map((f: any) => f.name).join(', ')
84
+ }`
85
+ );
86
+ }
87
+
88
+ // Find the message type
89
+ const messageType = fileDescriptor.messageType?.find((m: any) => m.name === messageName);
90
+
91
+ if (!messageType) {
92
+ const availableMessages = fileDescriptor.messageType?.map((m: any) => m.name).join(', ') || 'none';
93
+ throw new Error(
94
+ `Message '${messageName}' not found in ${protoFileName}. Available messages: ${availableMessages}`
95
+ );
96
+ }
97
+
98
+ // Encode the DescriptorProto to binary
99
+ const descriptorProtoBytes = descriptor.DescriptorProto.encode(messageType).finish();
100
+
101
+ // Convert to base64
102
+ return Buffer.from(descriptorProtoBytes).toString('base64');
103
+ }