@alepha/protobuf 0.13.0 → 0.13.2

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/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@ import "dayjs";
7
7
 
8
8
  //#region ../alepha/src/core/constants/KIND.d.ts
9
9
  /**
10
- * Used for identifying descriptors.
10
+ * Used for identifying primitives.
11
11
  *
12
12
  * @internal
13
13
  */
@@ -60,34 +60,49 @@ interface ServiceSubstitution<T extends object = any> {
60
60
  */
61
61
  type ServiceEntry<T extends object = any> = Service<T> | ServiceSubstitution<T>;
62
62
  //#endregion
63
- //#region ../alepha/src/core/helpers/descriptor.d.ts
64
- interface DescriptorArgs<T extends object = {}> {
63
+ //#region ../alepha/src/core/helpers/primitive.d.ts
64
+ interface PrimitiveArgs<T extends object = {}> {
65
65
  options: T;
66
66
  alepha: Alepha;
67
67
  service: InstantiableClass<Service>;
68
68
  module?: Service;
69
69
  }
70
- interface DescriptorConfig {
70
+ interface PrimitiveConfig {
71
71
  propertyKey: string;
72
72
  service: InstantiableClass<Service>;
73
73
  module?: Service;
74
74
  }
75
- declare abstract class Descriptor<T extends object = {}> {
75
+ declare abstract class Primitive<T extends object = {}> {
76
76
  protected readonly alepha: Alepha;
77
77
  readonly options: T;
78
- readonly config: DescriptorConfig;
79
- constructor(args: DescriptorArgs<T>);
78
+ readonly config: PrimitiveConfig;
79
+ constructor(args: PrimitiveArgs<T>);
80
80
  /**
81
- * Called automatically by Alepha after the descriptor is created.
81
+ * Called automatically by Alepha after the primitive is created.
82
82
  */
83
83
  protected onInit(): void;
84
84
  }
85
- type DescriptorFactoryLike<T extends object = any> = {
85
+ type PrimitiveFactoryLike<T extends object = any> = {
86
86
  (options: T): any;
87
87
  [KIND]: any;
88
88
  };
89
89
  //#endregion
90
- //#region ../alepha/src/core/descriptors/$inject.d.ts
90
+ //#region ../alepha/src/core/interfaces/Async.d.ts
91
+ /**
92
+ * Represents a value that can be either a value or a promise of value.
93
+ */
94
+ type Async<T> = T | Promise<T>;
95
+ //#endregion
96
+ //#region ../alepha/src/core/interfaces/LoggerInterface.d.ts
97
+ interface LoggerInterface {
98
+ trace(message: string, data?: unknown): void;
99
+ debug(message: string, data?: unknown): void;
100
+ info(message: string, data?: unknown): void;
101
+ warn(message: string, data?: unknown): void;
102
+ error(message: string, data?: unknown): void;
103
+ }
104
+ //#endregion
105
+ //#region ../alepha/src/core/primitives/$inject.d.ts
91
106
  interface InjectOptions<T extends object = any> {
92
107
  /**
93
108
  * - 'transient' → Always a new instance on every inject. Zero caching.
@@ -112,8 +127,8 @@ interface InjectOptions<T extends object = any> {
112
127
  parent?: Service | null;
113
128
  }
114
129
  //#endregion
115
- //#region ../alepha/src/core/descriptors/$module.d.ts
116
- interface ModuleDescriptorOptions {
130
+ //#region ../alepha/src/core/primitives/$module.d.ts
131
+ interface ModulePrimitiveOptions {
117
132
  /**
118
133
  * Name of the module.
119
134
  *
@@ -128,9 +143,9 @@ interface ModuleDescriptorOptions {
128
143
  */
129
144
  services?: Array<Service>;
130
145
  /**
131
- * List of $descriptors to register in the module.
146
+ * List of $primitives to register in the module.
132
147
  */
133
- descriptors?: Array<DescriptorFactoryLike>;
148
+ primitives?: Array<PrimitiveFactoryLike>;
134
149
  /**
135
150
  * By default, module will register ALL services.
136
151
  * You can override this behavior by providing a register function.
@@ -144,7 +159,7 @@ interface ModuleDescriptorOptions {
144
159
  * Base class for all modules.
145
160
  */
146
161
  declare abstract class Module {
147
- abstract readonly options: ModuleDescriptorOptions;
162
+ abstract readonly options: ModulePrimitiveOptions;
148
163
  abstract register(alepha: Alepha): void;
149
164
  static NAME_REGEX: RegExp;
150
165
  /**
@@ -159,21 +174,6 @@ declare abstract class Module {
159
174
  static of(ctor: Service): Service<Module> | undefined;
160
175
  }
161
176
  //#endregion
162
- //#region ../alepha/src/core/interfaces/Async.d.ts
163
- /**
164
- * Represents a value that can be either a value or a promise of value.
165
- */
166
- type Async<T> = T | Promise<T>;
167
- //#endregion
168
- //#region ../alepha/src/core/interfaces/LoggerInterface.d.ts
169
- interface LoggerInterface {
170
- trace(message: string, data?: unknown): void;
171
- debug(message: string, data?: unknown): void;
172
- info(message: string, data?: unknown): void;
173
- warn(message: string, data?: unknown): void;
174
- error(message: string, data?: unknown): void;
175
- }
176
- //#endregion
177
177
  //#region ../alepha/src/core/providers/AlsProvider.d.ts
178
178
  type AsyncLocalStorageData = any;
179
179
  declare class AlsProvider {
@@ -379,7 +379,7 @@ declare class EventManager {
379
379
  }): Promise<void>;
380
380
  }
381
381
  //#endregion
382
- //#region ../alepha/src/core/descriptors/$atom.d.ts
382
+ //#region ../alepha/src/core/primitives/$atom.d.ts
383
383
  type AtomOptions<T extends TAtomObject, N extends string> = {
384
384
  name: N;
385
385
  schema: T;
@@ -508,7 +508,7 @@ type OnlyArray<T extends object> = { [K in keyof T]: NonNullable<T[K]> extends A
508
508
  * // You can access the environment variables using alepha.env
509
509
  * console.log(alepha.env.MY_VAR); // "value"
510
510
  *
511
- * // But you should use $env() descriptor to get typed values from the environment.
511
+ * // But you should use $env() primitive to get typed values from the environment.
512
512
  * class App {
513
513
  * env = $env(
514
514
  * t.object({
@@ -521,7 +521,7 @@ type OnlyArray<T extends object> = { [K in keyof T]: NonNullable<T[K]> extends A
521
521
  * ### Modules
522
522
  *
523
523
  * Modules are a way to group services together.
524
- * You can register a module using the `$module` descriptor.
524
+ * You can register a module using the `$module` primitive.
525
525
  *
526
526
  * ```ts
527
527
  * import { $module } from "alepha";
@@ -539,7 +539,7 @@ type OnlyArray<T extends object> = { [K in keyof T]: NonNullable<T[K]> extends A
539
539
  * ### Hooks
540
540
  *
541
541
  * Hooks are a way to run async functions from all registered providers/services.
542
- * You can register a hook using the `$hook` descriptor.
542
+ * You can register a hook using the `$hook` primitive.
543
543
  *
544
544
  * ```ts
545
545
  * import { $hook } from "alepha";
@@ -636,9 +636,9 @@ declare class Alepha {
636
636
  use: Service;
637
637
  }>;
638
638
  /**
639
- * Registry of descriptors.
639
+ * Registry of primitives.
640
640
  */
641
- protected descriptorRegistry: Map<Service<Descriptor<{}>>, Descriptor<{}>[]>;
641
+ protected primitiveRegistry: Map<Service<Primitive<{}>>, Primitive<{}>[]>;
642
642
  /**
643
643
  * List of all services + how they are provided.
644
644
  */
@@ -658,7 +658,7 @@ declare class Alepha {
658
658
  /**
659
659
  * State manager to store arbitrary values.
660
660
  */
661
- get state(): StateManager<State>;
661
+ get store(): StateManager<State>;
662
662
  /**
663
663
  * Codec manager for encoding and decoding data with different formats.
664
664
  *
@@ -731,7 +731,7 @@ declare class Alepha {
731
731
  * Starts the App.
732
732
  *
733
733
  * - Lock any further changes to the container.
734
- * - Run "configure" hook for all services. Descriptors will be processed.
734
+ * - Run "configure" hook for all services. Primitives will be processed.
735
735
  * - Run "start" hook for all services. Providers will connect/listen/...
736
736
  * - Run "ready" hook for all services. This is the point where the App is ready to serve requests.
737
737
  *
@@ -836,13 +836,13 @@ declare class Alepha {
836
836
  }>;
837
837
  services<T extends object>(base: Service<T>): Array<T>;
838
838
  /**
839
- * Get all descriptors of the specified type.
839
+ * Get all primitives of the specified type.
840
840
  */
841
- descriptors<TDescriptor extends Descriptor>(factory: {
842
- [KIND]: InstantiableClass<TDescriptor>;
843
- } | string): Array<TDescriptor>;
841
+ primitives<TPrimitive extends Primitive>(factory: {
842
+ [KIND]: InstantiableClass<TPrimitive>;
843
+ } | string): Array<TPrimitive>;
844
844
  protected new<T extends object>(service: Service<T>, args?: any[]): T;
845
- protected processDescriptor(value: Descriptor, propertyKey?: string): void;
845
+ protected processPrimitive(value: Primitive, propertyKey?: string): void;
846
846
  }
847
847
  interface Hook<T extends keyof Hooks = any> {
848
848
  caller?: Service;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@alepha/protobuf",
3
3
  "description": "Protocol Buffers (Protobuf) codec support for Alepha framework.",
4
4
  "author": "Nicolas Foures",
5
- "version": "0.13.0",
5
+ "version": "0.13.2",
6
6
  "type": "module",
7
7
  "engines": {
8
8
  "node": ">=22.0.0"
@@ -18,13 +18,13 @@
18
18
  "protobufjs": "^7.5.4"
19
19
  },
20
20
  "devDependencies": {
21
- "alepha": "0.13.0",
21
+ "alepha": "0.13.2",
22
22
  "tsdown": "^0.16.7",
23
23
  "typescript": "^5.9.3",
24
24
  "vitest": "^4.0.14"
25
25
  },
26
26
  "peerDependencies": {
27
- "alepha": "0.13.0"
27
+ "alepha": "0.13.2"
28
28
  },
29
29
  "scripts": {
30
30
  "lint": "alepha lint",
@@ -1,27 +0,0 @@
1
- //#region rolldown:runtime
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") {
10
- for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
- key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) {
13
- __defProp(to, key, {
14
- get: ((k) => from[k]).bind(null, key),
15
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
- });
17
- }
18
- }
19
- }
20
- return to;
21
- };
22
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
- value: mod,
24
- enumerable: true
25
- }) : target, mod));
26
-
27
- //#endregion
package/dist/index.cjs DELETED
@@ -1,309 +0,0 @@
1
- //#region rolldown:runtime
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") {
10
- for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
- key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) {
13
- __defProp(to, key, {
14
- get: ((k) => from[k]).bind(null, key),
15
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
- });
17
- }
18
- }
19
- }
20
- return to;
21
- };
22
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
- value: mod,
24
- enumerable: true
25
- }) : target, mod));
26
-
27
- //#endregion
28
- let alepha = require("alepha");
29
- let protobufjs = require("protobufjs");
30
- protobufjs = __toESM(protobufjs);
31
- require("alepha/datetime");
32
-
33
- //#region src/providers/ProtobufProvider.ts
34
- var ProtobufProvider = class {
35
- alepha = (0, alepha.$inject)(alepha.Alepha);
36
- schemas = /* @__PURE__ */ new Map();
37
- protobuf = protobufjs.default;
38
- enumDefinitions = /* @__PURE__ */ new Map();
39
- /**
40
- * Encode an object to a Uint8Array.
41
- */
42
- encode(schema, message) {
43
- return this.parse(schema).encode(message).finish();
44
- }
45
- /**
46
- * Decode a Uint8Array to an object.
47
- */
48
- decode(schema, data) {
49
- return this.parse(schema).decode(data);
50
- }
51
- /**
52
- * Parse a TypeBox schema to a Protobuf Type schema ready for encoding/decoding.
53
- */
54
- parse(schema, typeName = "root.Target") {
55
- const exists = this.schemas.get(schema);
56
- if (exists) return exists;
57
- const type = this.protobuf.parse(schema).root.lookupType(typeName);
58
- this.schemas.set(schema, type);
59
- return type;
60
- }
61
- /**
62
- * Convert a TypeBox schema to a Protobuf schema as a string.
63
- */
64
- createProtobufSchema(schema, options = {}) {
65
- const { rootName = "root", mainMessageName = "Target" } = options;
66
- this.enumDefinitions.clear();
67
- const context = {
68
- proto: `package ${rootName};\nsyntax = "proto3";\n\n`,
69
- fieldIndex: 1
70
- };
71
- if (alepha.t.schema.isObject(schema)) {
72
- const { message, subMessages } = this.parseObjectWithDependencies(schema, mainMessageName);
73
- for (const [enumName, values] of this.enumDefinitions) context.proto += this.generateEnumDefinition(enumName, values);
74
- context.proto += subMessages.join("");
75
- context.proto += message;
76
- }
77
- return context.proto;
78
- }
79
- /**
80
- * Parse an object schema with dependencies (sub-messages).
81
- */
82
- parseObjectWithDependencies(obj, parentName) {
83
- if (!alepha.t.schema.isObject(obj)) return {
84
- message: "",
85
- subMessages: []
86
- };
87
- const fields = [];
88
- const subMessages = [];
89
- let fieldIndex = 1;
90
- for (const [key, value] of Object.entries(obj.properties)) {
91
- if (alepha.t.schema.isArray(value)) {
92
- if (this.isEnum(value.items)) {
93
- const enumValues = this.getEnumValues(value.items);
94
- const enumName = this.registerEnum(key, enumValues);
95
- fields.push(` repeated ${enumName} ${key} = ${fieldIndex++};`);
96
- continue;
97
- }
98
- if (alepha.t.schema.isObject(value.items)) {
99
- const subMessageName = "title" in value.items && typeof value.items.title === "string" ? value.items.title : `${parentName}_${key}`;
100
- const { message: subMessage, subMessages: nestedSubMessages } = this.parseObjectWithDependencies(value.items, subMessageName);
101
- subMessages.push(...nestedSubMessages);
102
- subMessages.push(subMessage);
103
- fields.push(` repeated ${subMessageName} ${key} = ${fieldIndex++};`);
104
- continue;
105
- }
106
- const itemType = this.convertType(value.items);
107
- fields.push(` repeated ${itemType} ${key} = ${fieldIndex++};`);
108
- continue;
109
- }
110
- if (alepha.t.schema.isObject(value)) {
111
- const subMessageName = "title" in value && typeof value.title === "string" ? value.title : `${parentName}_${key}`;
112
- const { message: subMessage, subMessages: nestedSubMessages } = this.parseObjectWithDependencies(value, subMessageName);
113
- subMessages.push(...nestedSubMessages);
114
- subMessages.push(subMessage);
115
- fields.push(` ${subMessageName} ${key} = ${fieldIndex++};`);
116
- continue;
117
- }
118
- if (alepha.t.schema.isUnion(value)) {
119
- const nonNullType = value.anyOf.find((type) => !alepha.t.schema.isNull(type));
120
- if (nonNullType) {
121
- if (this.isEnum(nonNullType)) {
122
- const enumValues = this.getEnumValues(nonNullType);
123
- const enumName = this.registerEnum(key, enumValues);
124
- fields.push(` ${enumName} ${key} = ${fieldIndex++};`);
125
- continue;
126
- }
127
- if (alepha.t.schema.isObject(nonNullType)) {
128
- const subMessageName = "title" in nonNullType && typeof nonNullType.title === "string" ? nonNullType.title : `${parentName}_${key}`;
129
- const { message: subMessage, subMessages: nestedSubMessages } = this.parseObjectWithDependencies(nonNullType, subMessageName);
130
- subMessages.push(...nestedSubMessages);
131
- subMessages.push(subMessage);
132
- fields.push(` ${subMessageName} ${key} = ${fieldIndex++};`);
133
- continue;
134
- }
135
- const fieldType$1 = this.convertType(nonNullType);
136
- fields.push(` ${fieldType$1} ${key} = ${fieldIndex++};`);
137
- continue;
138
- }
139
- }
140
- if (alepha.t.schema.isRecord(value)) {
141
- let valueSchema;
142
- if ("additionalProperties" in value && value.additionalProperties && typeof value.additionalProperties === "object") valueSchema = value.additionalProperties;
143
- else if (value.patternProperties && typeof value.patternProperties === "object") {
144
- const patterns = Object.values(value.patternProperties);
145
- if (patterns.length > 0 && typeof patterns[0] === "object") valueSchema = patterns[0];
146
- }
147
- if (valueSchema) {
148
- const valueType = this.convertType(valueSchema);
149
- fields.push(` map<string, ${valueType}> ${key} = ${fieldIndex++};`);
150
- continue;
151
- }
152
- }
153
- if (this.isEnum(value)) {
154
- const enumValues = this.getEnumValues(value);
155
- const enumName = this.registerEnum(key, enumValues);
156
- fields.push(` ${enumName} ${key} = ${fieldIndex++};`);
157
- continue;
158
- }
159
- const fieldType = this.convertType(value);
160
- fields.push(` ${fieldType} ${key} = ${fieldIndex++};`);
161
- }
162
- return {
163
- message: `message ${parentName} {\n${fields.join("\n")}\n}\n`,
164
- subMessages
165
- };
166
- }
167
- /**
168
- * Convert a primitive TypeBox schema type to a Protobuf spec type.
169
- */
170
- convertType(schema) {
171
- if (alepha.t.schema.isBoolean(schema)) return "bool";
172
- if (alepha.t.schema.isNumber(schema) && schema.format === "int64") return "int64";
173
- if (alepha.t.schema.isNumber(schema)) return "double";
174
- if (alepha.t.schema.isInteger(schema)) return "int32";
175
- if (alepha.t.schema.isBigInt(schema)) return "int64";
176
- if (alepha.t.schema.isString(schema)) return "string";
177
- if (alepha.t.schema.isUnion(schema)) {
178
- const nonNullType = schema.anyOf.find((type) => !alepha.t.schema.isNull(type));
179
- if (nonNullType) return this.convertType(nonNullType);
180
- }
181
- if (alepha.t.schema.isOptional(schema)) return this.convertType(schema);
182
- if (alepha.t.schema.isUnsafe(schema)) return "string";
183
- throw new Error(`Unsupported type: ${JSON.stringify(schema)}`);
184
- }
185
- /**
186
- * Check if a schema is an enum type.
187
- * TypeBox enums have an "enum" property with an array of values.
188
- */
189
- isEnum(schema) {
190
- return "enum" in schema && Array.isArray(schema.enum);
191
- }
192
- /**
193
- * Extract enum values from a TypeBox enum schema.
194
- */
195
- getEnumValues(schema) {
196
- if ("enum" in schema && Array.isArray(schema.enum)) return schema.enum.map(String);
197
- return [];
198
- }
199
- /**
200
- * Register an enum and return its type name.
201
- * Generates a PascalCase name from the field name.
202
- */
203
- registerEnum(fieldName, values) {
204
- const enumName = fieldName.charAt(0).toUpperCase() + fieldName.slice(1);
205
- const valueKey = values.join(",");
206
- const existingEnum = Array.from(this.enumDefinitions.entries()).find(([_, enumValues]) => enumValues.join(",") === valueKey);
207
- if (existingEnum) return existingEnum[0];
208
- this.enumDefinitions.set(enumName, values);
209
- return enumName;
210
- }
211
- /**
212
- * Generate a protobuf enum definition.
213
- */
214
- generateEnumDefinition(enumName, values) {
215
- return `enum ${enumName} {\n${values.map((value, index) => ` ${value} = ${index};`).join("\n")}\n}\n`;
216
- }
217
- };
218
-
219
- //#endregion
220
- //#region src/providers/ProtobufSchemaCodec.ts
221
- /**
222
- * ProtobufSchemaCodec handles encoding/decoding for Protobuf format.
223
- *
224
- * Key differences from JSON codec:
225
- * - BigInt values are kept as BigInt (not converted to string)
226
- * - Date values are converted to ISO strings for protobuf compatibility
227
- * - Binary data (Uint8Array) is kept as-is
228
- * - Proto3 default values are applied when decoding (to handle omitted fields)
229
- */
230
- var ProtobufSchemaCodec = class extends alepha.SchemaCodec {
231
- protobufProvider = (0, alepha.$inject)(ProtobufProvider);
232
- decoder = new TextDecoder();
233
- encodeToString(schema, value) {
234
- const binary = this.encodeToBinary(schema, value);
235
- if (typeof Buffer !== "undefined") return Buffer.from(binary).toString("base64");
236
- else return btoa(String.fromCharCode(...binary));
237
- }
238
- encodeToBinary(schema, value) {
239
- const proto = this.protobufProvider.createProtobufSchema(schema);
240
- return this.protobufProvider.encode(proto, value);
241
- }
242
- decode(schema, value) {
243
- const proto = this.protobufProvider.createProtobufSchema(schema);
244
- if (value instanceof Uint8Array) return this.applyProto3Defaults(schema, this.protobufProvider.decode(proto, value));
245
- if (typeof value === "string") return this.applyProto3Defaults(schema, this.protobufProvider.decode(proto, typeof Buffer !== "undefined" ? Uint8Array.from(Buffer.from(value, "base64")) : Uint8Array.from(atob(value).split("").map((c) => c.charCodeAt(0)))));
246
- throw new alepha.AlephaError(`Unsupported value type for Protobuf decoding: ${typeof value}`);
247
- }
248
- /**
249
- * Apply proto3 default values for fields that were omitted during encoding.
250
- * Proto3 omits fields with default values, so we need to restore them.
251
- * Also converts enum integers back to their string values.
252
- */
253
- applyProto3Defaults(schema, value) {
254
- if (!value || typeof value !== "object") return value;
255
- if (alepha.t.schema.isObject(schema)) {
256
- const result = { ...value };
257
- for (const [key, propSchema] of Object.entries(schema.properties)) if (!(key in result) || result[key] === void 0) result[key] = this.getProto3Default(propSchema);
258
- else if (this.isEnum(propSchema)) result[key] = this.convertEnumValue(propSchema, result[key]);
259
- else if (typeof result[key] === "object" && result[key] !== null) result[key] = this.applyProto3Defaults(propSchema, result[key]);
260
- return result;
261
- }
262
- if (alepha.t.schema.isArray(schema) && Array.isArray(value)) return value.map((item) => this.applyProto3Defaults(schema.items, item));
263
- return value;
264
- }
265
- /**
266
- * Check if a schema is an enum type.
267
- */
268
- isEnum(schema) {
269
- return "enum" in schema && Array.isArray(schema.enum);
270
- }
271
- /**
272
- * Convert an enum value from protobuf integer to TypeBox string.
273
- */
274
- convertEnumValue(schema, value) {
275
- if (typeof value === "number" && "enum" in schema && Array.isArray(schema.enum)) return schema.enum[value];
276
- return value;
277
- }
278
- /**
279
- * Get the proto3 default value for a schema type.
280
- */
281
- getProto3Default(schema) {
282
- if (alepha.t.schema.isOptional(schema) || alepha.t.schema.isUnion(schema)) return;
283
- if (alepha.t.schema.isArray(schema)) return [];
284
- if (alepha.t.schema.isRecord(schema)) return {};
285
- if (alepha.t.schema.isString(schema)) return "";
286
- if (alepha.t.schema.isNumber(schema)) return 0;
287
- if (alepha.t.schema.isInteger(schema)) return 0;
288
- if (alepha.t.schema.isBigInt(schema)) return BigInt(0);
289
- if (alepha.t.schema.isBoolean(schema)) return false;
290
- if (alepha.t.schema.isObject(schema)) return {};
291
- }
292
- };
293
-
294
- //#endregion
295
- //#region src/index.ts
296
- const AlephaProtobuf = (0, alepha.$module)({
297
- name: "alepha.protobuf",
298
- services: [ProtobufProvider, ProtobufSchemaCodec],
299
- register: (alepha$1) => {
300
- alepha$1.with(ProtobufProvider);
301
- alepha$1.codec.register("protobuf", alepha$1.inject(ProtobufSchemaCodec));
302
- }
303
- });
304
-
305
- //#endregion
306
- exports.AlephaProtobuf = AlephaProtobuf;
307
- exports.ProtobufProvider = ProtobufProvider;
308
- exports.ProtobufSchemaCodec = ProtobufSchemaCodec;
309
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","names":["Alepha","t","fields: string[]","subMessages: string[]","fieldType","valueSchema: TSchema | undefined","SchemaCodec","AlephaError","t","result: any","alepha"],"sources":["../src/providers/ProtobufProvider.ts","../src/providers/ProtobufSchemaCodec.ts","../src/index.ts"],"sourcesContent":["import { $inject, Alepha, type TObject, type TSchema, t } from \"alepha\";\nimport type { Type } from \"protobufjs\";\nimport protobufjs from \"protobufjs\";\n\nexport class ProtobufProvider {\n protected readonly alepha = $inject(Alepha);\n protected readonly schemas: Map<string | TObject, Type> = new Map();\n protected readonly protobuf: typeof protobufjs = protobufjs;\n protected readonly enumDefinitions: Map<string, string[]> = new Map();\n\n /**\n * Encode an object to a Uint8Array.\n */\n public encode(schema: ProtobufSchema, message: any): Uint8Array {\n return this.parse(schema).encode(message).finish();\n }\n\n /**\n * Decode a Uint8Array to an object.\n */\n public decode<T = any>(schema: ProtobufSchema, data: Uint8Array): T {\n return this.parse(schema).decode(data) as T;\n }\n\n /**\n * Parse a TypeBox schema to a Protobuf Type schema ready for encoding/decoding.\n */\n public parse(schema: ProtobufSchema, typeName = \"root.Target\"): Type {\n const exists = this.schemas.get(schema);\n if (exists) {\n return exists;\n }\n\n const result = this.protobuf.parse(schema);\n const type = result.root.lookupType(typeName);\n this.schemas.set(schema, type);\n return type;\n }\n\n /**\n * Convert a TypeBox schema to a Protobuf schema as a string.\n */\n public createProtobufSchema(\n schema: TSchema,\n options: CreateProtobufSchemaOptions = {},\n ): string {\n const { rootName = \"root\", mainMessageName = \"Target\" } = options;\n // Clear enum definitions for this schema generation\n this.enumDefinitions.clear();\n\n const context = {\n proto: `package ${rootName};\\nsyntax = \"proto3\";\\n\\n`,\n fieldIndex: 1,\n };\n\n if (t.schema.isObject(schema)) {\n const { message, subMessages } = this.parseObjectWithDependencies(\n schema,\n mainMessageName,\n );\n\n // Add all enum definitions first\n for (const [enumName, values] of this.enumDefinitions) {\n context.proto += this.generateEnumDefinition(enumName, values);\n }\n\n // Add all sub-messages\n context.proto += subMessages.join(\"\");\n // Then add the main message\n context.proto += message;\n }\n\n return context.proto;\n }\n\n /**\n * Parse an object schema with dependencies (sub-messages).\n */\n protected parseObjectWithDependencies(\n obj: TSchema,\n parentName: string,\n ): { message: string; subMessages: string[] } {\n if (!t.schema.isObject(obj)) {\n return { message: \"\", subMessages: [] };\n }\n\n const fields: string[] = [];\n const subMessages: string[] = [];\n let fieldIndex = 1;\n\n for (const [key, value] of Object.entries(obj.properties)) {\n // Handle arrays\n if (t.schema.isArray(value)) {\n // Check if array items are enums\n if (this.isEnum(value.items)) {\n const enumValues = this.getEnumValues(value.items);\n const enumName = this.registerEnum(key, enumValues);\n fields.push(` repeated ${enumName} ${key} = ${fieldIndex++};`);\n continue;\n }\n\n if (t.schema.isObject(value.items)) {\n const subMessageName =\n \"title\" in value.items && typeof value.items.title === \"string\"\n ? value.items.title\n : `${parentName}_${key}`;\n const { message: subMessage, subMessages: nestedSubMessages } =\n this.parseObjectWithDependencies(value.items, subMessageName);\n subMessages.push(...nestedSubMessages);\n subMessages.push(subMessage);\n fields.push(` repeated ${subMessageName} ${key} = ${fieldIndex++};`);\n continue;\n }\n\n const itemType = this.convertType(value.items);\n fields.push(` repeated ${itemType} ${key} = ${fieldIndex++};`);\n continue;\n }\n\n // Handle nested objects\n if (t.schema.isObject(value)) {\n const subMessageName =\n \"title\" in value && typeof value.title === \"string\"\n ? value.title\n : `${parentName}_${key}`;\n const { message: subMessage, subMessages: nestedSubMessages } =\n this.parseObjectWithDependencies(value, subMessageName);\n subMessages.push(...nestedSubMessages);\n subMessages.push(subMessage);\n fields.push(` ${subMessageName} ${key} = ${fieldIndex++};`);\n continue;\n }\n\n // Handle union types (nullable fields)\n if (t.schema.isUnion(value)) {\n const nonNullType = value.anyOf.find(\n (type: TSchema) => !t.schema.isNull(type),\n );\n if (nonNullType) {\n // Check if it's an enum\n if (this.isEnum(nonNullType)) {\n const enumValues = this.getEnumValues(nonNullType);\n const enumName = this.registerEnum(key, enumValues);\n fields.push(` ${enumName} ${key} = ${fieldIndex++};`);\n continue;\n }\n\n if (t.schema.isObject(nonNullType)) {\n const subMessageName =\n \"title\" in nonNullType && typeof nonNullType.title === \"string\"\n ? nonNullType.title\n : `${parentName}_${key}`;\n const { message: subMessage, subMessages: nestedSubMessages } =\n this.parseObjectWithDependencies(nonNullType, subMessageName);\n subMessages.push(...nestedSubMessages);\n subMessages.push(subMessage);\n fields.push(` ${subMessageName} ${key} = ${fieldIndex++};`);\n continue;\n }\n const fieldType = this.convertType(nonNullType);\n fields.push(` ${fieldType} ${key} = ${fieldIndex++};`);\n continue;\n }\n }\n\n // Handle records (maps)\n if (t.schema.isRecord(value)) {\n // TypeBox records use additionalProperties or patternProperties for the value type\n let valueSchema: TSchema | undefined;\n if (\n \"additionalProperties\" in value &&\n value.additionalProperties &&\n typeof value.additionalProperties === \"object\"\n ) {\n valueSchema = value.additionalProperties;\n } else if (\n value.patternProperties &&\n typeof value.patternProperties === \"object\"\n ) {\n // Get the first pattern property (usually \"^(.*)$\" or similar)\n const patterns = Object.values(value.patternProperties);\n if (patterns.length > 0 && typeof patterns[0] === \"object\") {\n valueSchema = patterns[0] as TSchema;\n }\n }\n\n if (valueSchema) {\n const valueType = this.convertType(valueSchema);\n fields.push(` map<string, ${valueType}> ${key} = ${fieldIndex++};`);\n continue;\n }\n }\n\n // Handle enum fields\n if (this.isEnum(value)) {\n const enumValues = this.getEnumValues(value);\n const enumName = this.registerEnum(key, enumValues);\n fields.push(` ${enumName} ${key} = ${fieldIndex++};`);\n continue;\n }\n\n // Handle regular fields\n const fieldType = this.convertType(value);\n fields.push(` ${fieldType} ${key} = ${fieldIndex++};`);\n }\n\n const message = `message ${parentName} {\\n${fields.join(\"\\n\")}\\n}\\n`;\n return { message, subMessages };\n }\n\n /**\n * Convert a primitive TypeBox schema type to a Protobuf spec type.\n */\n protected convertType(schema: TSchema): string {\n if (t.schema.isBoolean(schema)) return \"bool\";\n if (t.schema.isNumber(schema) && schema.format === \"int64\") return \"int64\";\n if (t.schema.isNumber(schema)) return \"double\";\n if (t.schema.isInteger(schema)) return \"int32\";\n if (t.schema.isBigInt(schema)) return \"int64\";\n if (t.schema.isString(schema)) return \"string\";\n\n // Handle union types (nullable)\n if (t.schema.isUnion(schema)) {\n // Find the non-null type in the union\n const nonNullType = schema.anyOf.find(\n (type: TSchema) => !t.schema.isNull(type),\n );\n if (nonNullType) {\n return this.convertType(nonNullType);\n }\n }\n\n // Handle optional types\n if (t.schema.isOptional(schema)) {\n return this.convertType(schema);\n }\n\n // Handle unsafe types (like enums)\n if (t.schema.isUnsafe(schema)) {\n // if it's an enum or other unsafe types, default to string\n return \"string\";\n }\n\n throw new Error(`Unsupported type: ${JSON.stringify(schema)}`);\n }\n\n /**\n * Check if a schema is an enum type.\n * TypeBox enums have an \"enum\" property with an array of values.\n */\n protected isEnum(schema: TSchema): boolean {\n return \"enum\" in schema && Array.isArray(schema.enum);\n }\n\n /**\n * Extract enum values from a TypeBox enum schema.\n */\n protected getEnumValues(schema: TSchema): string[] {\n if (\"enum\" in schema && Array.isArray(schema.enum)) {\n return schema.enum.map(String);\n }\n return [];\n }\n\n /**\n * Register an enum and return its type name.\n * Generates a PascalCase name from the field name.\n */\n protected registerEnum(fieldName: string, values: string[]): string {\n // Capitalize first letter of field name for enum type name\n const enumName = fieldName.charAt(0).toUpperCase() + fieldName.slice(1);\n\n // Check if we already have this exact enum registered\n const valueKey = values.join(\",\");\n const existingEnum = Array.from(this.enumDefinitions.entries()).find(\n ([_, enumValues]) => enumValues.join(\",\") === valueKey,\n );\n\n if (existingEnum) {\n // Reuse existing enum with same values\n return existingEnum[0];\n }\n\n // Register new enum\n this.enumDefinitions.set(enumName, values);\n return enumName;\n }\n\n /**\n * Generate a protobuf enum definition.\n */\n protected generateEnumDefinition(enumName: string, values: string[]): string {\n const enumValues = values\n .map((value, index) => ` ${value} = ${index};`)\n .join(\"\\n\");\n return `enum ${enumName} {\\n${enumValues}\\n}\\n`;\n }\n}\n\nexport type ProtobufSchema = string;\n\nexport interface CreateProtobufSchemaOptions {\n rootName?: string;\n mainMessageName?: string;\n}\n","import {\n $inject,\n AlephaError,\n SchemaCodec,\n type Static,\n type TSchema,\n t,\n} from \"alepha\";\nimport \"alepha/datetime\";\nimport { ProtobufProvider } from \"./ProtobufProvider.ts\";\n\n/**\n * ProtobufSchemaCodec handles encoding/decoding for Protobuf format.\n *\n * Key differences from JSON codec:\n * - BigInt values are kept as BigInt (not converted to string)\n * - Date values are converted to ISO strings for protobuf compatibility\n * - Binary data (Uint8Array) is kept as-is\n * - Proto3 default values are applied when decoding (to handle omitted fields)\n */\nexport class ProtobufSchemaCodec extends SchemaCodec {\n protected protobufProvider = $inject(ProtobufProvider);\n protected decoder = new TextDecoder();\n\n public encodeToString<T extends TSchema>(\n schema: T,\n value: Static<T>,\n ): string {\n const binary = this.encodeToBinary(schema, value);\n // convert binary to base64 string for text representation\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(binary).toString(\"base64\");\n } else {\n return btoa(String.fromCharCode(...binary));\n }\n }\n\n public encodeToBinary<T extends TSchema>(\n schema: T,\n value: Static<T>,\n ): Uint8Array {\n const proto = this.protobufProvider.createProtobufSchema(schema);\n return this.protobufProvider.encode(proto, value);\n }\n\n public decode<T>(schema: TSchema, value: unknown): T {\n // First decode from protobuf binary to object\n const proto = this.protobufProvider.createProtobufSchema(schema);\n\n if (value instanceof Uint8Array) {\n return this.applyProto3Defaults(\n schema,\n this.protobufProvider.decode(proto, value),\n );\n }\n\n if (typeof value === \"string\") {\n return this.applyProto3Defaults(\n schema,\n this.protobufProvider.decode(\n proto,\n typeof Buffer !== \"undefined\"\n ? Uint8Array.from(Buffer.from(value, \"base64\"))\n : Uint8Array.from(\n atob(value)\n .split(\"\")\n .map((c) => c.charCodeAt(0)),\n ),\n ),\n );\n }\n\n throw new AlephaError(\n `Unsupported value type for Protobuf decoding: ${typeof value}`,\n );\n }\n\n /**\n * Apply proto3 default values for fields that were omitted during encoding.\n * Proto3 omits fields with default values, so we need to restore them.\n * Also converts enum integers back to their string values.\n */\n protected applyProto3Defaults(schema: TSchema, value: any): any {\n if (!value || typeof value !== \"object\") {\n return value;\n }\n\n if (t.schema.isObject(schema)) {\n const result: any = { ...value };\n\n for (const [key, propSchema] of Object.entries(schema.properties)) {\n if (!(key in result) || result[key] === undefined) {\n // Apply proto3 default values based on type\n result[key] = this.getProto3Default(propSchema);\n } else {\n // Convert enum integers to strings\n if (this.isEnum(propSchema)) {\n result[key] = this.convertEnumValue(propSchema, result[key]);\n } else if (typeof result[key] === \"object\" && result[key] !== null) {\n // Recursively apply defaults to nested objects\n result[key] = this.applyProto3Defaults(propSchema, result[key]);\n }\n }\n }\n\n return result;\n }\n\n if (t.schema.isArray(schema) && Array.isArray(value)) {\n return value.map((item) => this.applyProto3Defaults(schema.items, item));\n }\n\n return value;\n }\n\n /**\n * Check if a schema is an enum type.\n */\n protected isEnum(schema: TSchema): boolean {\n return \"enum\" in schema && Array.isArray(schema.enum);\n }\n\n /**\n * Convert an enum value from protobuf integer to TypeBox string.\n */\n protected convertEnumValue(schema: TSchema, value: any): any {\n if (\n typeof value === \"number\" &&\n \"enum\" in schema &&\n Array.isArray(schema.enum)\n ) {\n // Protobuf encodes enums as integers, convert back to string\n return schema.enum[value];\n }\n return value;\n }\n\n /**\n * Get the proto3 default value for a schema type.\n */\n protected getProto3Default(schema: TSchema): any {\n // Handle nullable/optional types - they can be undefined\n if (t.schema.isOptional(schema) || t.schema.isUnion(schema)) {\n return undefined;\n }\n\n // Handle arrays - default is empty array\n if (t.schema.isArray(schema)) {\n return [];\n }\n\n // Handle records (maps) - default is empty object\n if (t.schema.isRecord(schema)) {\n return {};\n }\n\n // Handle primitive types\n if (t.schema.isString(schema)) return \"\";\n if (t.schema.isNumber(schema)) return 0;\n if (t.schema.isInteger(schema)) return 0;\n if (t.schema.isBigInt(schema)) return BigInt(0);\n if (t.schema.isBoolean(schema)) return false;\n\n // For objects, return empty object (will be filled in recursively)\n if (t.schema.isObject(schema)) {\n return {};\n }\n\n return undefined;\n }\n}\n","import { $module } from \"alepha\";\nimport { ProtobufProvider } from \"./providers/ProtobufProvider.ts\";\nimport { ProtobufSchemaCodec } from \"./providers/ProtobufSchemaCodec.ts\";\n\nexport * from \"./providers/ProtobufProvider.ts\";\nexport * from \"./providers/ProtobufSchemaCodec.ts\";\n\nexport const AlephaProtobuf = $module({\n name: \"alepha.protobuf\",\n services: [ProtobufProvider, ProtobufSchemaCodec],\n register: (alepha) => {\n alepha.with(ProtobufProvider);\n alepha.codec.register(\"protobuf\", alepha.inject(ProtobufSchemaCodec));\n },\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,IAAa,mBAAb,MAA8B;CAC5B,AAAmB,6BAAiBA,cAAO;CAC3C,AAAmB,0BAAuC,IAAI,KAAK;CACnE,AAAmB,WAA8B;CACjD,AAAmB,kCAAyC,IAAI,KAAK;;;;CAKrE,AAAO,OAAO,QAAwB,SAA0B;AAC9D,SAAO,KAAK,MAAM,OAAO,CAAC,OAAO,QAAQ,CAAC,QAAQ;;;;;CAMpD,AAAO,OAAgB,QAAwB,MAAqB;AAClE,SAAO,KAAK,MAAM,OAAO,CAAC,OAAO,KAAK;;;;;CAMxC,AAAO,MAAM,QAAwB,WAAW,eAAqB;EACnE,MAAM,SAAS,KAAK,QAAQ,IAAI,OAAO;AACvC,MAAI,OACF,QAAO;EAIT,MAAM,OADS,KAAK,SAAS,MAAM,OAAO,CACtB,KAAK,WAAW,SAAS;AAC7C,OAAK,QAAQ,IAAI,QAAQ,KAAK;AAC9B,SAAO;;;;;CAMT,AAAO,qBACL,QACA,UAAuC,EAAE,EACjC;EACR,MAAM,EAAE,WAAW,QAAQ,kBAAkB,aAAa;AAE1D,OAAK,gBAAgB,OAAO;EAE5B,MAAM,UAAU;GACd,OAAO,WAAW,SAAS;GAC3B,YAAY;GACb;AAED,MAAIC,SAAE,OAAO,SAAS,OAAO,EAAE;GAC7B,MAAM,EAAE,SAAS,gBAAgB,KAAK,4BACpC,QACA,gBACD;AAGD,QAAK,MAAM,CAAC,UAAU,WAAW,KAAK,gBACpC,SAAQ,SAAS,KAAK,uBAAuB,UAAU,OAAO;AAIhE,WAAQ,SAAS,YAAY,KAAK,GAAG;AAErC,WAAQ,SAAS;;AAGnB,SAAO,QAAQ;;;;;CAMjB,AAAU,4BACR,KACA,YAC4C;AAC5C,MAAI,CAACA,SAAE,OAAO,SAAS,IAAI,CACzB,QAAO;GAAE,SAAS;GAAI,aAAa,EAAE;GAAE;EAGzC,MAAMC,SAAmB,EAAE;EAC3B,MAAMC,cAAwB,EAAE;EAChC,IAAI,aAAa;AAEjB,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,IAAI,WAAW,EAAE;AAEzD,OAAIF,SAAE,OAAO,QAAQ,MAAM,EAAE;AAE3B,QAAI,KAAK,OAAO,MAAM,MAAM,EAAE;KAC5B,MAAM,aAAa,KAAK,cAAc,MAAM,MAAM;KAClD,MAAM,WAAW,KAAK,aAAa,KAAK,WAAW;AACnD,YAAO,KAAK,cAAc,SAAS,GAAG,IAAI,KAAK,aAAa,GAAG;AAC/D;;AAGF,QAAIA,SAAE,OAAO,SAAS,MAAM,MAAM,EAAE;KAClC,MAAM,iBACJ,WAAW,MAAM,SAAS,OAAO,MAAM,MAAM,UAAU,WACnD,MAAM,MAAM,QACZ,GAAG,WAAW,GAAG;KACvB,MAAM,EAAE,SAAS,YAAY,aAAa,sBACxC,KAAK,4BAA4B,MAAM,OAAO,eAAe;AAC/D,iBAAY,KAAK,GAAG,kBAAkB;AACtC,iBAAY,KAAK,WAAW;AAC5B,YAAO,KAAK,cAAc,eAAe,GAAG,IAAI,KAAK,aAAa,GAAG;AACrE;;IAGF,MAAM,WAAW,KAAK,YAAY,MAAM,MAAM;AAC9C,WAAO,KAAK,cAAc,SAAS,GAAG,IAAI,KAAK,aAAa,GAAG;AAC/D;;AAIF,OAAIA,SAAE,OAAO,SAAS,MAAM,EAAE;IAC5B,MAAM,iBACJ,WAAW,SAAS,OAAO,MAAM,UAAU,WACvC,MAAM,QACN,GAAG,WAAW,GAAG;IACvB,MAAM,EAAE,SAAS,YAAY,aAAa,sBACxC,KAAK,4BAA4B,OAAO,eAAe;AACzD,gBAAY,KAAK,GAAG,kBAAkB;AACtC,gBAAY,KAAK,WAAW;AAC5B,WAAO,KAAK,KAAK,eAAe,GAAG,IAAI,KAAK,aAAa,GAAG;AAC5D;;AAIF,OAAIA,SAAE,OAAO,QAAQ,MAAM,EAAE;IAC3B,MAAM,cAAc,MAAM,MAAM,MAC7B,SAAkB,CAACA,SAAE,OAAO,OAAO,KAAK,CAC1C;AACD,QAAI,aAAa;AAEf,SAAI,KAAK,OAAO,YAAY,EAAE;MAC5B,MAAM,aAAa,KAAK,cAAc,YAAY;MAClD,MAAM,WAAW,KAAK,aAAa,KAAK,WAAW;AACnD,aAAO,KAAK,KAAK,SAAS,GAAG,IAAI,KAAK,aAAa,GAAG;AACtD;;AAGF,SAAIA,SAAE,OAAO,SAAS,YAAY,EAAE;MAClC,MAAM,iBACJ,WAAW,eAAe,OAAO,YAAY,UAAU,WACnD,YAAY,QACZ,GAAG,WAAW,GAAG;MACvB,MAAM,EAAE,SAAS,YAAY,aAAa,sBACxC,KAAK,4BAA4B,aAAa,eAAe;AAC/D,kBAAY,KAAK,GAAG,kBAAkB;AACtC,kBAAY,KAAK,WAAW;AAC5B,aAAO,KAAK,KAAK,eAAe,GAAG,IAAI,KAAK,aAAa,GAAG;AAC5D;;KAEF,MAAMG,cAAY,KAAK,YAAY,YAAY;AAC/C,YAAO,KAAK,KAAKA,YAAU,GAAG,IAAI,KAAK,aAAa,GAAG;AACvD;;;AAKJ,OAAIH,SAAE,OAAO,SAAS,MAAM,EAAE;IAE5B,IAAII;AACJ,QACE,0BAA0B,SAC1B,MAAM,wBACN,OAAO,MAAM,yBAAyB,SAEtC,eAAc,MAAM;aAEpB,MAAM,qBACN,OAAO,MAAM,sBAAsB,UACnC;KAEA,MAAM,WAAW,OAAO,OAAO,MAAM,kBAAkB;AACvD,SAAI,SAAS,SAAS,KAAK,OAAO,SAAS,OAAO,SAChD,eAAc,SAAS;;AAI3B,QAAI,aAAa;KACf,MAAM,YAAY,KAAK,YAAY,YAAY;AAC/C,YAAO,KAAK,iBAAiB,UAAU,IAAI,IAAI,KAAK,aAAa,GAAG;AACpE;;;AAKJ,OAAI,KAAK,OAAO,MAAM,EAAE;IACtB,MAAM,aAAa,KAAK,cAAc,MAAM;IAC5C,MAAM,WAAW,KAAK,aAAa,KAAK,WAAW;AACnD,WAAO,KAAK,KAAK,SAAS,GAAG,IAAI,KAAK,aAAa,GAAG;AACtD;;GAIF,MAAM,YAAY,KAAK,YAAY,MAAM;AACzC,UAAO,KAAK,KAAK,UAAU,GAAG,IAAI,KAAK,aAAa,GAAG;;AAIzD,SAAO;GAAE,SADO,WAAW,WAAW,MAAM,OAAO,KAAK,KAAK,CAAC;GAC5C;GAAa;;;;;CAMjC,AAAU,YAAY,QAAyB;AAC7C,MAAIJ,SAAE,OAAO,UAAU,OAAO,CAAE,QAAO;AACvC,MAAIA,SAAE,OAAO,SAAS,OAAO,IAAI,OAAO,WAAW,QAAS,QAAO;AACnE,MAAIA,SAAE,OAAO,SAAS,OAAO,CAAE,QAAO;AACtC,MAAIA,SAAE,OAAO,UAAU,OAAO,CAAE,QAAO;AACvC,MAAIA,SAAE,OAAO,SAAS,OAAO,CAAE,QAAO;AACtC,MAAIA,SAAE,OAAO,SAAS,OAAO,CAAE,QAAO;AAGtC,MAAIA,SAAE,OAAO,QAAQ,OAAO,EAAE;GAE5B,MAAM,cAAc,OAAO,MAAM,MAC9B,SAAkB,CAACA,SAAE,OAAO,OAAO,KAAK,CAC1C;AACD,OAAI,YACF,QAAO,KAAK,YAAY,YAAY;;AAKxC,MAAIA,SAAE,OAAO,WAAW,OAAO,CAC7B,QAAO,KAAK,YAAY,OAAO;AAIjC,MAAIA,SAAE,OAAO,SAAS,OAAO,CAE3B,QAAO;AAGT,QAAM,IAAI,MAAM,qBAAqB,KAAK,UAAU,OAAO,GAAG;;;;;;CAOhE,AAAU,OAAO,QAA0B;AACzC,SAAO,UAAU,UAAU,MAAM,QAAQ,OAAO,KAAK;;;;;CAMvD,AAAU,cAAc,QAA2B;AACjD,MAAI,UAAU,UAAU,MAAM,QAAQ,OAAO,KAAK,CAChD,QAAO,OAAO,KAAK,IAAI,OAAO;AAEhC,SAAO,EAAE;;;;;;CAOX,AAAU,aAAa,WAAmB,QAA0B;EAElE,MAAM,WAAW,UAAU,OAAO,EAAE,CAAC,aAAa,GAAG,UAAU,MAAM,EAAE;EAGvE,MAAM,WAAW,OAAO,KAAK,IAAI;EACjC,MAAM,eAAe,MAAM,KAAK,KAAK,gBAAgB,SAAS,CAAC,CAAC,MAC7D,CAAC,GAAG,gBAAgB,WAAW,KAAK,IAAI,KAAK,SAC/C;AAED,MAAI,aAEF,QAAO,aAAa;AAItB,OAAK,gBAAgB,IAAI,UAAU,OAAO;AAC1C,SAAO;;;;;CAMT,AAAU,uBAAuB,UAAkB,QAA0B;AAI3E,SAAO,QAAQ,SAAS,MAHL,OAChB,KAAK,OAAO,UAAU,KAAK,MAAM,KAAK,MAAM,GAAG,CAC/C,KAAK,KAAK,CAC4B;;;;;;;;;;;;;;;ACnR7C,IAAa,sBAAb,cAAyCK,mBAAY;CACnD,AAAU,uCAA2B,iBAAiB;CACtD,AAAU,UAAU,IAAI,aAAa;CAErC,AAAO,eACL,QACA,OACQ;EACR,MAAM,SAAS,KAAK,eAAe,QAAQ,MAAM;AAEjD,MAAI,OAAO,WAAW,YACpB,QAAO,OAAO,KAAK,OAAO,CAAC,SAAS,SAAS;MAE7C,QAAO,KAAK,OAAO,aAAa,GAAG,OAAO,CAAC;;CAI/C,AAAO,eACL,QACA,OACY;EACZ,MAAM,QAAQ,KAAK,iBAAiB,qBAAqB,OAAO;AAChE,SAAO,KAAK,iBAAiB,OAAO,OAAO,MAAM;;CAGnD,AAAO,OAAU,QAAiB,OAAmB;EAEnD,MAAM,QAAQ,KAAK,iBAAiB,qBAAqB,OAAO;AAEhE,MAAI,iBAAiB,WACnB,QAAO,KAAK,oBACV,QACA,KAAK,iBAAiB,OAAO,OAAO,MAAM,CAC3C;AAGH,MAAI,OAAO,UAAU,SACnB,QAAO,KAAK,oBACV,QACA,KAAK,iBAAiB,OACpB,OACA,OAAO,WAAW,cACd,WAAW,KAAK,OAAO,KAAK,OAAO,SAAS,CAAC,GAC7C,WAAW,KACT,KAAK,MAAM,CACR,MAAM,GAAG,CACT,KAAK,MAAM,EAAE,WAAW,EAAE,CAAC,CAC/B,CACN,CACF;AAGH,QAAM,IAAIC,mBACR,iDAAiD,OAAO,QACzD;;;;;;;CAQH,AAAU,oBAAoB,QAAiB,OAAiB;AAC9D,MAAI,CAAC,SAAS,OAAO,UAAU,SAC7B,QAAO;AAGT,MAAIC,SAAE,OAAO,SAAS,OAAO,EAAE;GAC7B,MAAMC,SAAc,EAAE,GAAG,OAAO;AAEhC,QAAK,MAAM,CAAC,KAAK,eAAe,OAAO,QAAQ,OAAO,WAAW,CAC/D,KAAI,EAAE,OAAO,WAAW,OAAO,SAAS,OAEtC,QAAO,OAAO,KAAK,iBAAiB,WAAW;YAG3C,KAAK,OAAO,WAAW,CACzB,QAAO,OAAO,KAAK,iBAAiB,YAAY,OAAO,KAAK;YACnD,OAAO,OAAO,SAAS,YAAY,OAAO,SAAS,KAE5D,QAAO,OAAO,KAAK,oBAAoB,YAAY,OAAO,KAAK;AAKrE,UAAO;;AAGT,MAAID,SAAE,OAAO,QAAQ,OAAO,IAAI,MAAM,QAAQ,MAAM,CAClD,QAAO,MAAM,KAAK,SAAS,KAAK,oBAAoB,OAAO,OAAO,KAAK,CAAC;AAG1E,SAAO;;;;;CAMT,AAAU,OAAO,QAA0B;AACzC,SAAO,UAAU,UAAU,MAAM,QAAQ,OAAO,KAAK;;;;;CAMvD,AAAU,iBAAiB,QAAiB,OAAiB;AAC3D,MACE,OAAO,UAAU,YACjB,UAAU,UACV,MAAM,QAAQ,OAAO,KAAK,CAG1B,QAAO,OAAO,KAAK;AAErB,SAAO;;;;;CAMT,AAAU,iBAAiB,QAAsB;AAE/C,MAAIA,SAAE,OAAO,WAAW,OAAO,IAAIA,SAAE,OAAO,QAAQ,OAAO,CACzD;AAIF,MAAIA,SAAE,OAAO,QAAQ,OAAO,CAC1B,QAAO,EAAE;AAIX,MAAIA,SAAE,OAAO,SAAS,OAAO,CAC3B,QAAO,EAAE;AAIX,MAAIA,SAAE,OAAO,SAAS,OAAO,CAAE,QAAO;AACtC,MAAIA,SAAE,OAAO,SAAS,OAAO,CAAE,QAAO;AACtC,MAAIA,SAAE,OAAO,UAAU,OAAO,CAAE,QAAO;AACvC,MAAIA,SAAE,OAAO,SAAS,OAAO,CAAE,QAAO,OAAO,EAAE;AAC/C,MAAIA,SAAE,OAAO,UAAU,OAAO,CAAE,QAAO;AAGvC,MAAIA,SAAE,OAAO,SAAS,OAAO,CAC3B,QAAO,EAAE;;;;;;AC9Jf,MAAa,qCAAyB;CACpC,MAAM;CACN,UAAU,CAAC,kBAAkB,oBAAoB;CACjD,WAAW,aAAW;AACpB,WAAO,KAAK,iBAAiB;AAC7B,WAAO,MAAM,SAAS,YAAYE,SAAO,OAAO,oBAAoB,CAAC;;CAExE,CAAC"}