@aptre/common 0.35.3 → 0.36.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/README.md CHANGED
@@ -36,6 +36,31 @@ This repository provides the `aptre` CLI — a single tool that generates protob
36
36
  [starpc]: https://github.com/aperturerobotics/starpc
37
37
  [prost]: https://github.com/tokio-rs/prost
38
38
 
39
+ ## Stable Type IDs
40
+
41
+ A message can declare a stable type identifier with the `(typeid.id)` option:
42
+
43
+ ```protobuf
44
+ import "github.com/aperturerobotics/common/typeid/typeid.proto";
45
+
46
+ message CreateFile {
47
+ option (typeid.id) = "fs/create-file";
48
+
49
+ string path = 1;
50
+ }
51
+ ```
52
+
53
+ For each proto file with such messages, `aptre generate` writes
54
+ `*_typeid.pb.go` holding a `CreateFileTypeID` constant, a `TypeID()` method,
55
+ and the file's `[]typeid.Type` list (`OpsTypes` for `ops.proto`) pairing each
56
+ identifier with a constructor. The generator runs inside aptre, so it needs no
57
+ plugin binary. The generator rejects two messages in one file with the same
58
+ identifier; an application that builds a registry from several lists checks
59
+ the rest.
60
+
61
+ C++ builds that import the option also compile `typeid/typeid.pb.cc`; other
62
+ languages ignore it.
63
+
39
64
  ## Rust Support via WASI
40
65
 
41
66
  The Rust code generation uses an embedded [WASI] build of `protoc-gen-prost`, meaning **you don't need Cargo, rustc, or any Rust toolchain installed** to generate `.pb.rs` files. The prost plugin runs entirely within the wazero WebAssembly runtime alongside protoc itself.
@@ -217,6 +242,53 @@ The CLI flag takes precedence over `package.json`:
217
242
  aptre generate --language go
218
243
  ```
219
244
 
245
+ ### `aptre.rust`
246
+
247
+ Setting `aptre.rust` makes `aptre generate` compile the whole schema graph in a
248
+ single run and write one Rust file per schema, beside the schema, even when a
249
+ protobuf package spans several directories. Every other selected language still
250
+ uses the per-directory generator.
251
+
252
+ ```json
253
+ {
254
+ "aptre": {
255
+ "module": "example.com/app",
256
+ "languages": ["rust"],
257
+ "rust": {
258
+ "prostOptions": ["enable_type_names", "btree_map=."],
259
+ "exclude": [],
260
+ "descriptorSet": "wire/descriptors.bin",
261
+ "moduleFile": "wire/messages.rs",
262
+ "inventory": ".protoc-rust-files.txt"
263
+ }
264
+ }
265
+ }
266
+ ```
267
+
268
+ - `module` is the import path that prefixes the project's schemas. It defaults
269
+ to the `go.mod` module, so a project without `go.mod` must set it. Schemas
270
+ under `vendor/` keep the import path they have inside that directory.
271
+ - `prostOptions` are passed to the prost plugin in order. Use them for type
272
+ names, deterministic maps, boxed fields and `extern_path` mappings.
273
+ - `exclude` lists schema patterns to leave out of compilation.
274
+ - `descriptorSet` receives the serialized descriptors of the whole graph,
275
+ including imports and source information, for runtime reflection.
276
+ - `moduleFile` receives `include!` declarations that nest each generated file
277
+ under its protobuf package, naming each segment as Prost does (snake case,
278
+ `r#` for keywords).
279
+ - `inventory` lists every generated path. The next run removes files that the
280
+ inventory names but the schemas no longer produce.
281
+
282
+ Select schemas with `--targets`. Outputs are built in memory first and written
283
+ only when their bytes change. `aptre generate --check --language rust` compares
284
+ all outputs without writing, prints each `outdated:` path and exits non-zero.
285
+ The check never prepares dependencies: when `rpc` includes `starpc` and
286
+ `protoc-gen-starpc-rust` is not built, it fails and names the missing plugin;
287
+ run `aptre deps` first.
288
+
289
+ `tests/rust-graph/check.bash` generates a project with every kind of type path,
290
+ checks it, and runs the Rust tests over exactly that output.
291
+
220
292
  ### `aptre.tsImportBoundaries`
221
293
 
222
294
  `tsImportBoundaries` configures how generated TypeScript protobuf imports are
@@ -1,6 +1,5 @@
1
- import { OtherMsg } from './other/other.pb.js';
2
- import type { MessageType } from '@aptre/protobuf-es-lite/message';
3
- export declare const protobufPackage = "example";
1
+ import { OtherMsg } from "./other/other.pb.js";
2
+ import type { MessageType } from "@aptre/protobuf-es-lite/message";
4
3
  /**
5
4
  * ExampleMsg is an example message.
6
5
  *
@@ -9,14 +8,10 @@ export declare const protobufPackage = "example";
9
8
  export interface ExampleMsg {
10
9
  /**
11
10
  * ExampleField is an example field.
12
- *
13
- * @generated from field: string example_field = 1;
14
11
  */
15
12
  exampleField?: string;
16
13
  /**
17
14
  * OtherMsg is an example of an imported message field.
18
- *
19
- * @generated from field: example.other.OtherMsg other_msg = 2;
20
15
  */
21
16
  otherMsg?: OtherMsg;
22
17
  }
@@ -27,9 +22,18 @@ export declare const ExampleMsg: MessageType<ExampleMsg>;
27
22
  * @generated from message example.EchoMsg
28
23
  */
29
24
  export interface EchoMsg {
25
+ body?: string;
26
+ }
27
+ export declare const EchoMsg: MessageType<EchoMsg>;
28
+ /**
29
+ * TypedMsg is an example message with a stable type ID.
30
+ *
31
+ * @generated from message example.TypedMsg
32
+ */
33
+ export interface TypedMsg {
30
34
  /**
31
- * @generated from field: string body = 1;
35
+ * Body is an example field.
32
36
  */
33
37
  body?: string;
34
38
  }
35
- export declare const EchoMsg: MessageType<EchoMsg>;
39
+ export declare const TypedMsg: MessageType<TypedMsg>;
@@ -1,23 +1,18 @@
1
1
  // @generated by protoc-gen-es-lite unknown with parameter "target=ts,ts_nocheck=false"
2
2
  // @generated from file github.com/aperturerobotics/common/example/example.proto (package example, syntax proto3)
3
3
  /* eslint-disable */
4
- import { OtherMsg } from './other/other.pb.js';
5
- import { createMessageType } from '@aptre/protobuf-es-lite/message';
6
- import { ScalarType } from '@aptre/protobuf-es-lite/scalar';
7
- export const protobufPackage = 'example';
4
+ import { OtherMsg } from "./other/other.pb.js";
5
+ import { createMessageType } from "@aptre/protobuf-es-lite/message";
8
6
  export const ExampleMsg =
9
- /* @__PURE__ */ createMessageType({
10
- typeName: 'example.ExampleMsg',
11
- fields: [
12
- { no: 1, name: 'example_field', kind: 'scalar', T: ScalarType.STRING },
13
- { no: 2, name: 'other_msg', kind: 'message', T: () => OtherMsg },
14
- ],
15
- packedByDefault: true,
16
- });
17
- export const EchoMsg = /* @__PURE__ */ createMessageType({
18
- typeName: 'example.EchoMsg',
19
- fields: [
20
- { no: 1, name: 'body', kind: 'scalar', T: ScalarType.STRING },
21
- ],
22
- packedByDefault: true,
23
- });
7
+ /* @__PURE__ */ createMessageType("example.ExampleMsg", () => [
8
+ [1, "example_field", 9],
9
+ [2, "other_msg", 11, 0, OtherMsg.codec],
10
+ ]);
11
+ export const EchoMsg =
12
+ /* @__PURE__ */ createMessageType("example.EchoMsg", () => [
13
+ [1, "body", 9],
14
+ ]);
15
+ export const TypedMsg =
16
+ /* @__PURE__ */ createMessageType("example.TypedMsg", () => [
17
+ [1, "body", 9],
18
+ ]);
@@ -1,13 +1,13 @@
1
- import { EchoMsg } from './example.pb.js';
2
- import { MethodKind } from '@aptre/protobuf-es-lite';
3
- import { ProtoRpc } from 'starpc';
1
+ import { EchoMsg } from "./example.pb.js";
2
+ import { MethodKind } from "@aptre/protobuf-es-lite";
3
+ import { ProtoRpc, ServerContext } from "starpc";
4
4
  /**
5
5
  * Echoer service returns the given message.
6
6
  *
7
7
  * @generated from service example.Echoer
8
8
  */
9
9
  export declare const EchoerDefinition: {
10
- readonly typeName: 'example.Echoer';
10
+ readonly typeName: "example.Echoer";
11
11
  readonly methods: {
12
12
  /**
13
13
  * Echo returns the given message.
@@ -15,7 +15,7 @@ export declare const EchoerDefinition: {
15
15
  * @generated from rpc example.Echoer.Echo
16
16
  */
17
17
  readonly Echo: {
18
- readonly name: 'Echo';
18
+ readonly name: "Echo";
19
19
  readonly I: import("@aptre/protobuf-es-lite").MessageType<EchoMsg>;
20
20
  readonly O: import("@aptre/protobuf-es-lite").MessageType<EchoMsg>;
21
21
  readonly kind: MethodKind.Unary;
@@ -35,6 +35,19 @@ export interface Echoer {
35
35
  */
36
36
  Echo(request: EchoMsg, abortSignal?: AbortSignal): Promise<EchoMsg>;
37
37
  }
38
+ /**
39
+ * Echoer service returns the given message.
40
+ *
41
+ * @generated from service example.Echoer
42
+ */
43
+ export interface EchoerHandler {
44
+ /**
45
+ * Echo returns the given message.
46
+ *
47
+ * @generated from rpc example.Echoer.Echo
48
+ */
49
+ Echo(request: EchoMsg, abortSignal: AbortSignal, context: ServerContext): Promise<EchoMsg>;
50
+ }
38
51
  export declare const EchoerServiceName: "example.Echoer";
39
52
  export declare class EchoerClient implements Echoer {
40
53
  private readonly rpc;
@@ -1,15 +1,15 @@
1
1
  // @generated by protoc-gen-es-starpc none with parameter "target=ts,ts_nocheck=false"
2
2
  // @generated from file github.com/aperturerobotics/common/example/example.proto (package example, syntax proto3)
3
3
  /* eslint-disable */
4
- import { EchoMsg } from './example.pb.js';
5
- import { MethodKind } from '@aptre/protobuf-es-lite';
4
+ import { EchoMsg } from "./example.pb.js";
5
+ import { MethodKind } from "@aptre/protobuf-es-lite";
6
6
  /**
7
7
  * Echoer service returns the given message.
8
8
  *
9
9
  * @generated from service example.Echoer
10
10
  */
11
11
  export const EchoerDefinition = {
12
- typeName: 'example.Echoer',
12
+ typeName: "example.Echoer",
13
13
  methods: {
14
14
  /**
15
15
  * Echo returns the given message.
@@ -17,7 +17,7 @@ export const EchoerDefinition = {
17
17
  * @generated from rpc example.Echoer.Echo
18
18
  */
19
19
  Echo: {
20
- name: 'Echo',
20
+ name: "Echo",
21
21
  I: EchoMsg,
22
22
  O: EchoMsg,
23
23
  kind: MethodKind.Unary,
@@ -1,5 +1,4 @@
1
- import type { MessageType } from '@aptre/protobuf-es-lite/message';
2
- export declare const protobufPackage = "example.other";
1
+ import type { MessageType } from "@aptre/protobuf-es-lite/message";
3
2
  /**
4
3
  * OtherMsg is a different message from ExampleMsg.
5
4
  *
@@ -8,8 +7,6 @@ export declare const protobufPackage = "example.other";
8
7
  export interface OtherMsg {
9
8
  /**
10
9
  * FooField is an example field.
11
- *
12
- * @generated from field: uint32 foo_field = 1;
13
10
  */
14
11
  fooField?: number;
15
12
  }
@@ -1,14 +1,8 @@
1
1
  // @generated by protoc-gen-es-lite unknown with parameter "target=ts,ts_nocheck=false"
2
2
  // @generated from file github.com/aperturerobotics/common/example/other/other.proto (package example.other, syntax proto3)
3
3
  /* eslint-disable */
4
- import { createMessageType } from '@aptre/protobuf-es-lite/message';
5
- import { ScalarType } from '@aptre/protobuf-es-lite/scalar';
6
- export const protobufPackage = 'example.other';
4
+ import { createMessageType } from "@aptre/protobuf-es-lite/message";
7
5
  export const OtherMsg =
8
- /* @__PURE__ */ createMessageType({
9
- typeName: 'example.other.OtherMsg',
10
- fields: [
11
- { no: 1, name: 'foo_field', kind: 'scalar', T: ScalarType.UINT32 },
12
- ],
13
- packedByDefault: true,
14
- });
6
+ /* @__PURE__ */ createMessageType("example.other.OtherMsg", () => [
7
+ [1, "foo_field", 13],
8
+ ]);
@@ -0,0 +1 @@
1
+ export declare const protobufPackage = "typeid";
@@ -0,0 +1,4 @@
1
+ // @generated by protoc-gen-es-lite unknown with parameter "target=ts,ts_nocheck=false"
2
+ // @generated from file github.com/aperturerobotics/common/typeid/typeid.proto (package typeid, syntax proto3)
3
+ /* eslint-disable */
4
+ export const protobufPackage = 'typeid';
package/go.mod CHANGED
@@ -1,28 +1,30 @@
1
1
  module github.com/aperturerobotics/common
2
2
 
3
- go 1.25.0
3
+ go 1.27.0
4
4
 
5
5
  require (
6
6
  github.com/aperturerobotics/abseil-cpp v0.0.0-20260131110040-4bb56e2f9017 // aperture-2
7
7
  github.com/aperturerobotics/cli v1.1.0
8
- github.com/aperturerobotics/go-protoc-gen-prost v0.0.0-20260705010911-9f53feac967b // master
8
+ github.com/aperturerobotics/fastjson v0.1.2-0.20260705010846-94f343f5bb34
9
+ github.com/aperturerobotics/go-protoc-gen-prost v0.0.0-20261003014807-d46d22154f35 // master
9
10
  github.com/aperturerobotics/go-protoc-wasi v0.0.0-20260808023521-7b1595380c3f // master
10
- github.com/aperturerobotics/go-websocket v1.8.15-0.20260619192713-a096778f08c1 // indirect
11
- github.com/aperturerobotics/json-iterator-lite v1.1.0 // indirect
12
11
  github.com/aperturerobotics/protobuf v0.0.0-20260203024654-8201686529c4 // wasi
13
- github.com/aperturerobotics/protobuf-go-lite v0.18.0 // latest
14
- github.com/aperturerobotics/starpc v0.52.1 // master
15
- github.com/aperturerobotics/util v1.34.9 // indirect
12
+ github.com/aperturerobotics/protobuf-go-lite v0.19.1-0.20261016221735-380ab5fa526b // latest
13
+ github.com/aperturerobotics/starpc v0.52.3-0.20261003013036-4cdf88642ec9 // latest
14
+ github.com/pkg/errors v0.9.1
15
+ github.com/tetratelabs/wazero v1.12.0
16
+ golang.org/x/mod v0.40.0
17
+ google.golang.org/protobuf v1.36.11
18
+ gopkg.in/yaml.v3 v3.0.1
16
19
  )
17
20
 
18
21
  require (
22
+ github.com/aperturerobotics/go-websocket v1.8.15-0.20260619192713-a096778f08c1 // indirect
23
+ github.com/aperturerobotics/json-iterator-lite v1.1.0 // indirect
24
+ github.com/aperturerobotics/util v1.34.10-0.20260802062101-496aab6cefd2 // indirect
19
25
  github.com/libp2p/go-buffer-pool v0.1.0 // indirect
20
- github.com/pkg/errors v0.9.1
26
+ github.com/libp2p/go-yamux/v5 v5.1.0 // indirect
21
27
  github.com/sirupsen/logrus v1.9.5-0.20260629095817-a23d315dfebb // indirect
22
- github.com/tetratelabs/wazero v1.12.0
23
28
  github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 // indirect
24
- golang.org/x/mod v0.39.0
25
29
  golang.org/x/sys v0.47.0 // indirect
26
30
  )
27
-
28
- require github.com/libp2p/go-yamux/v5 v5.1.0 // indirect