@rocketmq/protobuf 0.1.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.
@@ -0,0 +1,21 @@
1
+
2
+
3
+ > @rocketmq/protobuf@0.1.0 build /home/edilson/learnspace/rocketmq-broker/client-ts/packages/protobuf
4
+ > tsup
5
+
6
+ CLI Building entry: src/index.ts
7
+ CLI Using tsconfig: tsconfig.json
8
+ CLI tsup v8.5.1
9
+ CLI Using tsup config: /home/edilson/learnspace/rocketmq-broker/client-ts/packages/protobuf/tsup.config.ts
10
+ CLI Target: es2022
11
+ CLI Cleaning output folder
12
+ ESM Build start
13
+ CJS Build start
14
+ CJS dist/index.cjs 1.65 KB
15
+ CJS ⚡️ Build success in 10ms
16
+ ESM dist/index.js 645.00 B
17
+ ESM ⚡️ Build success in 10ms
18
+ DTS Build start
19
+ DTS ⚡️ Build success in 896ms
20
+ DTS dist/index.d.ts 581.00 B
21
+ DTS dist/index.d.cts 581.00 B
package/dist/index.cjs ADDED
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ toProto: () => toProto
24
+ });
25
+ module.exports = __toCommonJS(index_exports);
26
+
27
+ // src/generator.ts
28
+ var import_schema = require("@rocketmq/schema");
29
+ function ensureFieldsRegistered(schema) {
30
+ if (import_schema.defaultRegistry.getFields(schema).length > 0) return;
31
+ try {
32
+ new schema();
33
+ } catch {
34
+ }
35
+ }
36
+ function toProto(schema) {
37
+ ensureFieldsRegistered(schema);
38
+ const fields = import_schema.defaultRegistry.getFields(schema);
39
+ if (fields.length === 0) {
40
+ throw new Error(`Schema '${schema.name}' has no @Field() decorators \u2014 cannot generate proto`);
41
+ }
42
+ const body = fields.map((f) => `${f.protoType} ${f.name} = ${f.number};`).join(" ");
43
+ return `syntax = "proto3"; message ${schema.name} { ${body} }`;
44
+ }
45
+ // Annotate the CommonJS export names for ESM import in node:
46
+ 0 && (module.exports = {
47
+ toProto
48
+ });
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Generates a proto3 schema string from a decorated class.
3
+ *
4
+ * Reads field metadata from the default SchemaRegistry and produces
5
+ * the exact format the Rust broker expects in the `x-schema` queue argument.
6
+ *
7
+ * Usage:
8
+ * const proto = toProto(NotificationClass);
9
+ * // => 'syntax = "proto3"; message Notification { string id = 1; int64 timestamp = 2; }'
10
+ */
11
+ /**
12
+ * Converts a decorated schema class to a proto3 definition string.
13
+ *
14
+ * @throws Error if the class has no @Field() decorators.
15
+ */
16
+ declare function toProto(schema: Function): string;
17
+
18
+ export { toProto };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Generates a proto3 schema string from a decorated class.
3
+ *
4
+ * Reads field metadata from the default SchemaRegistry and produces
5
+ * the exact format the Rust broker expects in the `x-schema` queue argument.
6
+ *
7
+ * Usage:
8
+ * const proto = toProto(NotificationClass);
9
+ * // => 'syntax = "proto3"; message Notification { string id = 1; int64 timestamp = 2; }'
10
+ */
11
+ /**
12
+ * Converts a decorated schema class to a proto3 definition string.
13
+ *
14
+ * @throws Error if the class has no @Field() decorators.
15
+ */
16
+ declare function toProto(schema: Function): string;
17
+
18
+ export { toProto };
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ // src/generator.ts
2
+ import { defaultRegistry } from "@rocketmq/schema";
3
+ function ensureFieldsRegistered(schema) {
4
+ if (defaultRegistry.getFields(schema).length > 0) return;
5
+ try {
6
+ new schema();
7
+ } catch {
8
+ }
9
+ }
10
+ function toProto(schema) {
11
+ ensureFieldsRegistered(schema);
12
+ const fields = defaultRegistry.getFields(schema);
13
+ if (fields.length === 0) {
14
+ throw new Error(`Schema '${schema.name}' has no @Field() decorators \u2014 cannot generate proto`);
15
+ }
16
+ const body = fields.map((f) => `${f.protoType} ${f.name} = ${f.number};`).join(" ");
17
+ return `syntax = "proto3"; message ${schema.name} { ${body} }`;
18
+ }
19
+ export {
20
+ toProto
21
+ };
package/package.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "@rocketmq/protobuf",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "import": "./dist/index.js",
8
+ "types": "./dist/index.d.ts"
9
+ }
10
+ },
11
+ "dependencies": {
12
+ "@rocketmq/schema": "0.1.0"
13
+ },
14
+ "scripts": {
15
+ "build": "tsup",
16
+ "test": "vitest run"
17
+ }
18
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Tests for toProto() — proto3 string generation.
3
+ *
4
+ * Covers: valid schemas, empty schemas (error), multi-field ordering,
5
+ * and the force-instantiation path for uninitialized classes.
6
+ */
7
+
8
+ import { describe, it, expect } from 'vitest';
9
+ import { toProto } from './generator.js';
10
+ import { Schema, Field, defaultRegistry } from '@rocketmq/schema';
11
+
12
+ describe('toProto', () => {
13
+ it('generates proto3 string for a single-field class', () => {
14
+ @Schema()
15
+ class SingleField {
16
+ @Field()
17
+ id!: string;
18
+ }
19
+ new SingleField();
20
+
21
+ const proto = toProto(SingleField);
22
+ expect(proto).toBe('syntax = "proto3"; message SingleField { string id = 1; }');
23
+ });
24
+
25
+ it('generates proto3 with multiple fields in order', () => {
26
+ @Schema()
27
+ class MultiField {
28
+ @Field()
29
+ name!: string;
30
+
31
+ @Field({ type: 'int32' })
32
+ age!: number;
33
+
34
+ @Field({ type: 'bool' })
35
+ active!: boolean;
36
+ }
37
+ new MultiField();
38
+
39
+ const proto = toProto(MultiField);
40
+ expect(proto).toBe(
41
+ 'syntax = "proto3"; message MultiField { string name = 1; int32 age = 2; bool active = 3; }',
42
+ );
43
+ });
44
+
45
+ it('throws for class with no @Field() decorators', () => {
46
+ @Schema()
47
+ class NoFields {}
48
+
49
+ expect(() => toProto(NoFields)).toThrow(
50
+ "Schema 'NoFields' has no @Field() decorators — cannot generate proto",
51
+ );
52
+ });
53
+
54
+ it('forces instantiation when fields are not yet registered', () => {
55
+ // Simulate a class that hasn't been instantiated yet
56
+ @Schema()
57
+ class LazyInit {
58
+ @Field()
59
+ value!: string;
60
+ }
61
+ // Do NOT call `new LazyInit()` — toProto should do it internally
62
+ const proto = toProto(LazyInit);
63
+ expect(proto).toContain('string value = 1');
64
+ });
65
+
66
+ it('handles class whose constructor throws', () => {
67
+ // WHY: toProto wraps instantiation in try/catch for classes
68
+ // that require constructor arguments
69
+ class ThrowingCtor {
70
+ @Field()
71
+ x!: string;
72
+
73
+ constructor() {
74
+ // Fields registered via addInitializer before the throw
75
+ throw new Error('required args');
76
+ }
77
+ }
78
+ // Force-register the field store entry
79
+ defaultRegistry.getOrCreateFields(ThrowingCtor);
80
+
81
+ // toProto will try `new ThrowingCtor()`, catch, and check fields
82
+ // Since addInitializer runs before constructor body, field might be registered
83
+ // If not, it should throw "no @Field() decorators"
84
+ try {
85
+ const proto = toProto(ThrowingCtor);
86
+ expect(proto).toContain('string x = 1');
87
+ } catch (err) {
88
+ expect((err as Error).message).toContain('no @Field() decorators');
89
+ }
90
+ });
91
+ });
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Generates a proto3 schema string from a decorated class.
3
+ *
4
+ * Reads field metadata from the default SchemaRegistry and produces
5
+ * the exact format the Rust broker expects in the `x-schema` queue argument.
6
+ *
7
+ * Usage:
8
+ * const proto = toProto(NotificationClass);
9
+ * // => 'syntax = "proto3"; message Notification { string id = 1; int64 timestamp = 2; }'
10
+ */
11
+
12
+ import { defaultRegistry } from '@rocketmq/schema';
13
+
14
+ /**
15
+ * Forces field registration by instantiating the class once.
16
+ *
17
+ * TC39 field decorators defer registration via `addInitializer`,
18
+ * which only runs on construction. If no instance exists yet,
19
+ * the registry will have zero fields for the class.
20
+ */
21
+ function ensureFieldsRegistered(schema: Function): void {
22
+ if (defaultRegistry.getFields(schema).length > 0) return;
23
+
24
+ try {
25
+ new (schema as new () => unknown)();
26
+ } catch {
27
+ // Constructor may throw — fields are registered via addInitializer
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Converts a decorated schema class to a proto3 definition string.
33
+ *
34
+ * @throws Error if the class has no @Field() decorators.
35
+ */
36
+ export function toProto(schema: Function): string {
37
+ ensureFieldsRegistered(schema);
38
+
39
+ const fields = defaultRegistry.getFields(schema);
40
+ if (fields.length === 0) {
41
+ throw new Error(`Schema '${schema.name}' has no @Field() decorators — cannot generate proto`);
42
+ }
43
+
44
+ const body = fields.map((f) => `${f.protoType} ${f.name} = ${f.number};`).join(' ');
45
+
46
+ return `syntax = "proto3"; message ${schema.name} { ${body} }`;
47
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { toProto } from './generator.js';
package/tsconfig.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "rootDir": "src"
6
+ },
7
+ "include": ["src"]
8
+ }
package/tsup.config.ts ADDED
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from "tsup";
2
+
3
+ export default defineConfig({
4
+ entry: ["src/index.ts"],
5
+ format: ["esm", "cjs"],
6
+ dts: true,
7
+ clean: true,
8
+ });