@alepha/protobuf 0.6.2 → 0.6.4

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.cjs CHANGED
@@ -122,3 +122,4 @@ ${fields.join("\n")}
122
122
  }
123
123
 
124
124
  exports.ProtobufProvider = ProtobufProvider;
125
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../src/providers/ProtobufProvider.ts"],"sourcesContent":["import type { Static, TObject, TSchema } from \"@alepha/core\";\nimport { $inject, Alepha, TypeGuard } from \"@alepha/core\";\nimport type { Type } from \"protobufjs\";\nimport protobufjs from \"protobufjs\";\n\nexport class ProtobufProvider {\n\tprotected readonly alepha = $inject(Alepha);\n\tprotected readonly schemas = new Map<TObject | string, Type>();\n\tprotected readonly protobuf = protobufjs;\n\n\t/**\n\t * Encode an object to a Uint8Array.\n\t *\n\t * @param schema - TypeBox schema used to generate the Protobuf schema.\n\t * @param data - Object to encode. Can be any object or string.\n\t */\n\tpublic encode(schema: TObject, data: any): Uint8Array {\n\t\treturn this.parse(schema).encode(this.alepha.parse(schema, data)).finish();\n\t}\n\n\t/**\n\t * Decode a Uint8Array to an object.\n\t *\n\t * @param schema\n\t * @param data\n\t */\n\tpublic decode<T extends TObject>(schema: T, data: Uint8Array): Static<T> {\n\t\treturn this.alepha.parse(schema, this.parse(schema).decode(data));\n\t}\n\n\t/**\n\t * Parse a TypeBox schema to a Protobuf Type schema ready for encoding/decoding.\n\t *\n\t * @param schema\n\t * @param typeName\n\t */\n\tpublic parse(\n\t\tschema: ProtobufSchema | TObject,\n\t\ttypeName = \"root.Target\",\n\t): Type {\n\t\tconst exists = this.schemas.get(schema);\n\t\tif (exists) return exists;\n\n\t\tconst pbSchema =\n\t\t\ttypeof schema === \"string\" ? schema : this.createProtobufSchema(schema);\n\t\tconst result = this.protobuf.parse(pbSchema);\n\t\tconst type = result.root.lookupType(typeName);\n\t\tthis.schemas.set(schema, type);\n\t\treturn type;\n\t}\n\n\t/**\n\t * Convert a TypeBox schema to a Protobuf schema as a string.\n\t *\n\t * @param schema\n\t * @param options\n\t */\n\tpublic createProtobufSchema(\n\t\tschema: TSchema,\n\t\toptions: CreateProtobufSchemaOptions = {},\n\t): string {\n\t\tconst { rootName = \"root\", mainMessageName = \"Target\" } = options;\n\t\tconst context = {\n\t\t\tproto: `package ${rootName};\\nsyntax = \"proto3\";\\n\\n`,\n\t\t\tfieldIndex: 1,\n\t\t};\n\n\t\tif (TypeGuard.IsObject(schema)) {\n\t\t\tconst proto = this.parseObject(schema, mainMessageName, context);\n\t\t\tcontext.proto += proto;\n\t\t}\n\n\t\treturn context.proto;\n\t}\n\n\t/**\n\t * Parse an object schema to a Protobuf message.\n\t *\n\t * @param obj\n\t * @param parentName\n\t * @param context\n\t * @protected\n\t */\n\tprotected parseObject(\n\t\tobj: TSchema,\n\t\tparentName: string,\n\t\tcontext: { proto: string; fieldIndex: number },\n\t): string {\n\t\tif (!TypeGuard.IsObject(obj)) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tconst fields: string[] = [];\n\n\t\tfor (const [key, value] of Object.entries(obj.properties)) {\n\t\t\tif (TypeGuard.IsArray(value)) {\n\t\t\t\tif (TypeGuard.IsObject(value.items)) {\n\t\t\t\t\tconst subMessageName = value.items.title ?? `${parentName}_${key}`;\n\t\t\t\t\tcontext.proto += this.parseObject(value.items, subMessageName, {\n\t\t\t\t\t\t...context,\n\t\t\t\t\t\tfieldIndex: 1,\n\t\t\t\t\t});\n\t\t\t\t\tfields.push(\n\t\t\t\t\t\t` repeated ${subMessageName} ${key} = ${context.fieldIndex++};`,\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst itemType = this.convertType(value.items);\n\t\t\t\tfields.push(` repeated ${itemType} ${key} = ${context.fieldIndex++};`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (TypeGuard.IsObject(value)) {\n\t\t\t\tconst subMessageName = `${parentName}_${key}`;\n\t\t\t\tcontext.proto += this.parseObject(value, subMessageName, context);\n\t\t\t\tfields.push(` ${subMessageName} ${key} = ${context.fieldIndex++};`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tfields.push(\n\t\t\t\t` ${this.convertType(value)} ${key} = ${context.fieldIndex++};`,\n\t\t\t);\n\t\t}\n\n\t\treturn `message ${parentName} {\\n${fields.join(\"\\n\")}\\n}\\n`;\n\t}\n\n\t/**\n\t * Convert a primitive TypeBox schema type to a Protobuf spec type.\n\t *\n\t * @param schema\n\t * @protected\n\t */\n\tprotected convertType(schema: TSchema): string {\n\t\tif (TypeGuard.IsInteger(schema)) return \"int32\";\n\t\tif (TypeGuard.IsNumber(schema)) return \"double\";\n\t\tif (TypeGuard.IsString(schema)) return \"string\";\n\t\tif (TypeGuard.IsBoolean(schema)) return \"bool\";\n\n\t\tthrow new Error(`Unsupported type: ${JSON.stringify(schema)}`);\n\t}\n}\n\nexport type ProtobufSchema = string;\n\nexport interface CreateProtobufSchemaOptions {\n\trootName?: string;\n\tmainMessageName?: string;\n}\n"],"names":["$inject","Alepha","TypeGuard"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -120,3 +120,4 @@ ${fields.join("\n")}
120
120
  }
121
121
 
122
122
  export { ProtobufProvider };
123
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/providers/ProtobufProvider.ts"],"sourcesContent":["import type { Static, TObject, TSchema } from \"@alepha/core\";\nimport { $inject, Alepha, TypeGuard } from \"@alepha/core\";\nimport type { Type } from \"protobufjs\";\nimport protobufjs from \"protobufjs\";\n\nexport class ProtobufProvider {\n\tprotected readonly alepha = $inject(Alepha);\n\tprotected readonly schemas = new Map<TObject | string, Type>();\n\tprotected readonly protobuf = protobufjs;\n\n\t/**\n\t * Encode an object to a Uint8Array.\n\t *\n\t * @param schema - TypeBox schema used to generate the Protobuf schema.\n\t * @param data - Object to encode. Can be any object or string.\n\t */\n\tpublic encode(schema: TObject, data: any): Uint8Array {\n\t\treturn this.parse(schema).encode(this.alepha.parse(schema, data)).finish();\n\t}\n\n\t/**\n\t * Decode a Uint8Array to an object.\n\t *\n\t * @param schema\n\t * @param data\n\t */\n\tpublic decode<T extends TObject>(schema: T, data: Uint8Array): Static<T> {\n\t\treturn this.alepha.parse(schema, this.parse(schema).decode(data));\n\t}\n\n\t/**\n\t * Parse a TypeBox schema to a Protobuf Type schema ready for encoding/decoding.\n\t *\n\t * @param schema\n\t * @param typeName\n\t */\n\tpublic parse(\n\t\tschema: ProtobufSchema | TObject,\n\t\ttypeName = \"root.Target\",\n\t): Type {\n\t\tconst exists = this.schemas.get(schema);\n\t\tif (exists) return exists;\n\n\t\tconst pbSchema =\n\t\t\ttypeof schema === \"string\" ? schema : this.createProtobufSchema(schema);\n\t\tconst result = this.protobuf.parse(pbSchema);\n\t\tconst type = result.root.lookupType(typeName);\n\t\tthis.schemas.set(schema, type);\n\t\treturn type;\n\t}\n\n\t/**\n\t * Convert a TypeBox schema to a Protobuf schema as a string.\n\t *\n\t * @param schema\n\t * @param options\n\t */\n\tpublic createProtobufSchema(\n\t\tschema: TSchema,\n\t\toptions: CreateProtobufSchemaOptions = {},\n\t): string {\n\t\tconst { rootName = \"root\", mainMessageName = \"Target\" } = options;\n\t\tconst context = {\n\t\t\tproto: `package ${rootName};\\nsyntax = \"proto3\";\\n\\n`,\n\t\t\tfieldIndex: 1,\n\t\t};\n\n\t\tif (TypeGuard.IsObject(schema)) {\n\t\t\tconst proto = this.parseObject(schema, mainMessageName, context);\n\t\t\tcontext.proto += proto;\n\t\t}\n\n\t\treturn context.proto;\n\t}\n\n\t/**\n\t * Parse an object schema to a Protobuf message.\n\t *\n\t * @param obj\n\t * @param parentName\n\t * @param context\n\t * @protected\n\t */\n\tprotected parseObject(\n\t\tobj: TSchema,\n\t\tparentName: string,\n\t\tcontext: { proto: string; fieldIndex: number },\n\t): string {\n\t\tif (!TypeGuard.IsObject(obj)) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tconst fields: string[] = [];\n\n\t\tfor (const [key, value] of Object.entries(obj.properties)) {\n\t\t\tif (TypeGuard.IsArray(value)) {\n\t\t\t\tif (TypeGuard.IsObject(value.items)) {\n\t\t\t\t\tconst subMessageName = value.items.title ?? `${parentName}_${key}`;\n\t\t\t\t\tcontext.proto += this.parseObject(value.items, subMessageName, {\n\t\t\t\t\t\t...context,\n\t\t\t\t\t\tfieldIndex: 1,\n\t\t\t\t\t});\n\t\t\t\t\tfields.push(\n\t\t\t\t\t\t` repeated ${subMessageName} ${key} = ${context.fieldIndex++};`,\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst itemType = this.convertType(value.items);\n\t\t\t\tfields.push(` repeated ${itemType} ${key} = ${context.fieldIndex++};`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (TypeGuard.IsObject(value)) {\n\t\t\t\tconst subMessageName = `${parentName}_${key}`;\n\t\t\t\tcontext.proto += this.parseObject(value, subMessageName, context);\n\t\t\t\tfields.push(` ${subMessageName} ${key} = ${context.fieldIndex++};`);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tfields.push(\n\t\t\t\t` ${this.convertType(value)} ${key} = ${context.fieldIndex++};`,\n\t\t\t);\n\t\t}\n\n\t\treturn `message ${parentName} {\\n${fields.join(\"\\n\")}\\n}\\n`;\n\t}\n\n\t/**\n\t * Convert a primitive TypeBox schema type to a Protobuf spec type.\n\t *\n\t * @param schema\n\t * @protected\n\t */\n\tprotected convertType(schema: TSchema): string {\n\t\tif (TypeGuard.IsInteger(schema)) return \"int32\";\n\t\tif (TypeGuard.IsNumber(schema)) return \"double\";\n\t\tif (TypeGuard.IsString(schema)) return \"string\";\n\t\tif (TypeGuard.IsBoolean(schema)) return \"bool\";\n\n\t\tthrow new Error(`Unsupported type: ${JSON.stringify(schema)}`);\n\t}\n}\n\nexport type ProtobufSchema = string;\n\nexport interface CreateProtobufSchemaOptions {\n\trootName?: string;\n\tmainMessageName?: string;\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,20 +1,24 @@
1
1
  {
2
2
  "name": "@alepha/protobuf",
3
- "version": "0.6.2",
3
+ "version": "0.6.4",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "src"
11
+ ],
8
12
  "dependencies": {
9
- "@alepha/core": "0.6.2",
10
- "protobufjs": "^7.5.0"
13
+ "@alepha/core": "0.6.4",
14
+ "protobufjs": "^7.5.1"
11
15
  },
12
16
  "devDependencies": {
13
17
  "pkgroll": "^2.12.2",
14
- "vitest": "^3.1.2"
18
+ "vitest": "^3.1.3"
15
19
  },
16
20
  "scripts": {
17
- "build": "pkgroll --clean-dist"
21
+ "build": "pkgroll --clean-dist --sourcemap"
18
22
  },
19
23
  "exports": {
20
24
  ".": {
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./providers/ProtobufProvider.ts";
@@ -0,0 +1,150 @@
1
+ import type { Static, TObject, TSchema } from "@alepha/core";
2
+ import { $inject, Alepha, TypeGuard } from "@alepha/core";
3
+ import type { Type } from "protobufjs";
4
+ import protobufjs from "protobufjs";
5
+
6
+ export class ProtobufProvider {
7
+ protected readonly alepha = $inject(Alepha);
8
+ protected readonly schemas = new Map<TObject | string, Type>();
9
+ protected readonly protobuf = protobufjs;
10
+
11
+ /**
12
+ * Encode an object to a Uint8Array.
13
+ *
14
+ * @param schema - TypeBox schema used to generate the Protobuf schema.
15
+ * @param data - Object to encode. Can be any object or string.
16
+ */
17
+ public encode(schema: TObject, data: any): Uint8Array {
18
+ return this.parse(schema).encode(this.alepha.parse(schema, data)).finish();
19
+ }
20
+
21
+ /**
22
+ * Decode a Uint8Array to an object.
23
+ *
24
+ * @param schema
25
+ * @param data
26
+ */
27
+ public decode<T extends TObject>(schema: T, data: Uint8Array): Static<T> {
28
+ return this.alepha.parse(schema, this.parse(schema).decode(data));
29
+ }
30
+
31
+ /**
32
+ * Parse a TypeBox schema to a Protobuf Type schema ready for encoding/decoding.
33
+ *
34
+ * @param schema
35
+ * @param typeName
36
+ */
37
+ public parse(
38
+ schema: ProtobufSchema | TObject,
39
+ typeName = "root.Target",
40
+ ): Type {
41
+ const exists = this.schemas.get(schema);
42
+ if (exists) return exists;
43
+
44
+ const pbSchema =
45
+ typeof schema === "string" ? schema : this.createProtobufSchema(schema);
46
+ const result = this.protobuf.parse(pbSchema);
47
+ const type = result.root.lookupType(typeName);
48
+ this.schemas.set(schema, type);
49
+ return type;
50
+ }
51
+
52
+ /**
53
+ * Convert a TypeBox schema to a Protobuf schema as a string.
54
+ *
55
+ * @param schema
56
+ * @param options
57
+ */
58
+ public createProtobufSchema(
59
+ schema: TSchema,
60
+ options: CreateProtobufSchemaOptions = {},
61
+ ): string {
62
+ const { rootName = "root", mainMessageName = "Target" } = options;
63
+ const context = {
64
+ proto: `package ${rootName};\nsyntax = "proto3";\n\n`,
65
+ fieldIndex: 1,
66
+ };
67
+
68
+ if (TypeGuard.IsObject(schema)) {
69
+ const proto = this.parseObject(schema, mainMessageName, context);
70
+ context.proto += proto;
71
+ }
72
+
73
+ return context.proto;
74
+ }
75
+
76
+ /**
77
+ * Parse an object schema to a Protobuf message.
78
+ *
79
+ * @param obj
80
+ * @param parentName
81
+ * @param context
82
+ * @protected
83
+ */
84
+ protected parseObject(
85
+ obj: TSchema,
86
+ parentName: string,
87
+ context: { proto: string; fieldIndex: number },
88
+ ): string {
89
+ if (!TypeGuard.IsObject(obj)) {
90
+ return "";
91
+ }
92
+
93
+ const fields: string[] = [];
94
+
95
+ for (const [key, value] of Object.entries(obj.properties)) {
96
+ if (TypeGuard.IsArray(value)) {
97
+ if (TypeGuard.IsObject(value.items)) {
98
+ const subMessageName = value.items.title ?? `${parentName}_${key}`;
99
+ context.proto += this.parseObject(value.items, subMessageName, {
100
+ ...context,
101
+ fieldIndex: 1,
102
+ });
103
+ fields.push(
104
+ ` repeated ${subMessageName} ${key} = ${context.fieldIndex++};`,
105
+ );
106
+ continue;
107
+ }
108
+
109
+ const itemType = this.convertType(value.items);
110
+ fields.push(` repeated ${itemType} ${key} = ${context.fieldIndex++};`);
111
+ continue;
112
+ }
113
+
114
+ if (TypeGuard.IsObject(value)) {
115
+ const subMessageName = `${parentName}_${key}`;
116
+ context.proto += this.parseObject(value, subMessageName, context);
117
+ fields.push(` ${subMessageName} ${key} = ${context.fieldIndex++};`);
118
+ continue;
119
+ }
120
+
121
+ fields.push(
122
+ ` ${this.convertType(value)} ${key} = ${context.fieldIndex++};`,
123
+ );
124
+ }
125
+
126
+ return `message ${parentName} {\n${fields.join("\n")}\n}\n`;
127
+ }
128
+
129
+ /**
130
+ * Convert a primitive TypeBox schema type to a Protobuf spec type.
131
+ *
132
+ * @param schema
133
+ * @protected
134
+ */
135
+ protected convertType(schema: TSchema): string {
136
+ if (TypeGuard.IsInteger(schema)) return "int32";
137
+ if (TypeGuard.IsNumber(schema)) return "double";
138
+ if (TypeGuard.IsString(schema)) return "string";
139
+ if (TypeGuard.IsBoolean(schema)) return "bool";
140
+
141
+ throw new Error(`Unsupported type: ${JSON.stringify(schema)}`);
142
+ }
143
+ }
144
+
145
+ export type ProtobufSchema = string;
146
+
147
+ export interface CreateProtobufSchemaOptions {
148
+ rootName?: string;
149
+ mainMessageName?: string;
150
+ }