@metaengine/protobuf-angular
v1.0.0
Published
Generate Angular gRPC-Web services and models from Protobuf definitions with native Angular DI and gRPC error handling
Maintainers
Readme
MetaEngine Protobuf Angular
Generate Angular gRPC-Web services and models from Protobuf definitions.
gRPC/Connect transport with native Angular dependency injection, HTTP interceptors, and gRPC-native error handling — generated straight from your .proto sources.
Installation
npm install --save-dev @metaengine/protobuf-angularOr use directly with npx:
npx @metaengine/protobuf-angular <input> <output>Requirements
- Node.js 18.0 or later
- .NET 8.0 or later runtime (Download)
- Angular 14.0 or later (for the generated code)
Quick Start
Recommended setup
npx @metaengine/protobuf-angular service.proto ./src/app/api \
--inject-function \
--error-handling \
--documentationProduction setup
npx @metaengine/protobuf-angular service.proto ./src/app/api \
--bearer-auth API_TOKEN \
--provided-in root \
--error-handlingWith npm scripts
{
"scripts": {
"generate:api": "metaengine-protobuf-angular service.proto ./src/app/api --inject-function --error-handling"
}
}CLI Options
| Option | Description | Default |
|--------|-------------|---------|
| --provided-in <value> | Angular injection scope (root, any, platform) | - |
| --base-url-token <name> | Injection token name for base URL | BASE_URL |
| --service-suffix <suffix> | Service naming suffix | Service |
| --options-threshold <n> | Parameter count for options object | 4 |
| --documentation | Generate JSDoc comments | false |
| --inject-function | Use inject() instead of constructor injection | false |
| --error-handling | gRPC-native error handling keyed on gRPC status codes | false |
| --bearer-auth <env-var-name> | Bearer token via a DI injection token; generates an Angular auth interceptor | - |
| --basic-auth <userEnv:passEnv> | Basic auth from two env vars; generates an Angular auth interceptor | - |
| --timeout <seconds> | gRPC-Connect protocol timeout (grpc-timeout header) on every call | - |
| --custom-header <header-name> | Declare a static header slot for runtime population. Repeatable. | - |
| --date-transformation | Convert google.protobuf.Timestamp response fields to Date objects | false |
| --types-barrel | Emit an index.ts barrel per folder plus a root index.ts | false |
| --clean | Clean output directory (remove files not in generation) | false |
| --verbose | Enable verbose logging | false |
| --type-mapping <name=target> | Override the TS type for a protobuf type. Repeatable. | - |
| --help, -h | Show help message | - |
Generated Code Structure
output/
├── models/ # One file per message/enum
│ ├── entity.ts # export interface Entity { ... }
│ ├── create-entity-request.ts
│ └── ...
├── services/ # One file per proto service
│ ├── entity.service.ts # All EntityService RPCs (@Injectable)
│ ├── base-api.service.ts # Shared base service (headers, request helpers)
│ └── ...
└── injection-token.ts # Base URL injection token- With
--error-handling:models/grpc-status-code.tsandmodels/grpc-error.tsare added. - With
--bearer-auth/--basic-auth:services/api-interceptors.tsis added (the interceptor pipeline +provideApiInterceptors()factory).
Angular features
Dependency injection
--provided-in root makes services tree-shakeable singletons. --base-url-token MY_API_URL names the injection token your services read for the base URL. --inject-function switches generated services to Angular's inject() over constructor injection.
Authentication (via interceptors)
npx @metaengine/protobuf-angular service.proto ./src/app/api --bearer-auth API_TOKENGenerates services/api-interceptors.ts with a bearerAuthInterceptor and an InjectionToken you provide at app bootstrap. Wire it up with the generated provideApiInterceptors():
bootstrapApplication(AppComponent, {
providers: [
provideApiInterceptors(),
{ provide: API_TOKEN, useFactory: () => authService.getAccessToken() },
],
});--basic-auth API_USER:API_PASS generates a basicAuthInterceptor instead.
Timeout
npx @metaengine/protobuf-angular service.proto ./src/app/api --timeout 30Emits a grpc-timeout header (Connect protocol-level timeout) on every request — the gRPC-native equivalent of an HTTP request timeout.
Custom headers
npx @metaengine/protobuf-angular service.proto ./src/app/api --custom-header X-Tenant-IDDeclares an empty header slot on the base service for you to populate at runtime. Repeatable. (Angular has no env-var access in the browser, so header values are set at runtime, not baked in.)
gRPC-native error handling
npx @metaengine/protobuf-angular service.proto ./src/app/api --error-handlingEmits a GrpcError type and a GrpcStatusCode taxonomy. Errors are classified by gRPC status code rather than HTTP status: NOT_FOUND / PERMISSION_DENIED return null; INVALID_ARGUMENT / ALREADY_EXISTS / FAILED_PRECONDITION return the error body; UNAUTHENTICATED / INTERNAL / UNAVAILABLE throw.
Type mapping overrides
Use --type-mapping to override the TS type emitted for a protobuf type, keyed by its fully-qualified name. Repeatable. Unsupported targets are hard errors.
| Target | Emitted TS type |
|--------|-----------------|
| string | string |
| number | number |
| Date | Date |
| boolean | boolean |
npx @metaengine/protobuf-angular service.proto ./src/app/api \
--type-mapping google.protobuf.Timestamp=string \
--type-mapping google.protobuf.Duration=stringInteger scalars (including
int64/uint64) map tonumberby design so request bodies surviveJSON.stringifyand parsed responses match the wire shape. Abiginttarget is therefore not offered.
Programmatic Usage
The NuGet package allows programmatic use in .NET projects. See the website documentation for the full C# API reference.
Support
- Issues: GitHub Issues
- Email: [email protected]
- Website: metaengine.eu
License
MIT License - see LICENSE file for details.
