Skip to content

feat: add @nexus.internal for interfaces that only an SDK calls - #336

Closed
moetemp wants to merge 1 commit into
moe/up/error-enumsfrom
moe/up/internal-interfaces
Closed

moetemp wants to merge 1 commit into
moe/up/error-enumsfrom
moe/up/internal-interfaces

Conversation

@moetemp

@moetemp moetemp commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

What changed?

This PR adds @nexus.internal, which marks an interface that only an SDK calls, so its package exports nothing.

/// @nexus.service-name "temporal.sdk.streams.v1.StreamWriter"
/// @nexus.internal
interface stream-writer { ... }
  • Python. The package's __init__.py exports nothing, and the SDK imports its modules. It keeps the operation registry, where a client looks up serialization contexts.
  • TypeScript. The package has no index.ts, and each top-level declaration is @internal, so stripInternal drops it from the published types.
  • .NET. Each type is internal in place of public. Its members stay public, so they are internal through their type. The SDK's tests see the types through InternalsVisibleTo.
  • Go. Nothing changes. A caller writes the output under an internal/ directory, Go's own rule.
  • Java ignores the directive with a warning.

nexgen refuses arguments on the directive.

A new sample, internal-service, shows it in the four languages, and it stays after the stream samples change. The stream sample's writer is internal too, so its tests import the service object from its module.

It sits on #335. The stack is #308, #310, #311, #297, #296, #303, #304, #309, #318, #319, #320, #321, #322, #323, #324, #325, #326, #327, #328, #329, #330, #331, #332, #333, #334, #335, then this PR.

Why?

Brook's writer is a service of the SDK's runtime, not of its users. The generated packages export it next to the Stream API today, and the published TypeScript and .NET types show it.

The design also renamed the Python modules with a leading underscore (_client.py, _models.py). This PR keeps their names, since the generated imports and the imports between packages name them, and sdk-python puts the package under its private _streams package already.

The .NET tests of the samples compile their own copy of the internal package, since InternalsVisibleTo on the samples' project would also expose the internal support helpers, which the tests compile too.

How did you test it?

A Python test checks that the internal package exports nothing, and calls its operation through its module. A TypeScript test calls the operation through its module and checks that the package has no index.ts. A .NET compile check calls the internal operation. A Java test checks the warning, a unit test checks the directive, and a rejection fixture covers the refusal.
cargo validate passes.

The package of an internal service exports nothing. Python's `__init__.py` has no exports,
TypeScript has no `index.ts` and marks each declaration `@internal`, and .NET types are `internal`.
@moetemp

moetemp commented Oct 28, 2026

Copy link
Copy Markdown
Contributor Author

Moved to moetemp/nexgen#97 for review first. It comes back here after that.

@moetemp moetemp closed this Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant