CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-grpc--proto-loader

gRPC utility library for loading .proto files

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

cli-tool.mddocs/

CLI Type Generation Tool

Command-line utility for generating TypeScript type definitions from .proto files, enabling type-safe gRPC development in TypeScript projects.

Capabilities

proto-loader-gen-types Command

The CLI tool generates TypeScript interface and type definitions from Protocol Buffer files.

proto-loader-gen-types [options] filenames...

Installation and Usage:

# Install package
npm install @grpc/proto-loader

# Generate types
npx proto-loader-gen-types --longs=String --enums=String --defaults --oneofs --grpcLib=@grpc/grpc-js --outDir=proto/ proto/*.proto

# Or use directly from node_modules
$(npm bin)/proto-loader-gen-types --outDir=types/ service.proto

Command Options

OptionTypeDefaultDescription
--helpboolean-Show help information
--versionboolean-Show version number
--keepCasebooleanfalsePreserve the case of field names
--longsstring"Long"The type for 64-bit integer values. Can be "String", "Number"
--enumsstring"number"The type for enum fields. Can be "String"
--bytesstring"Buffer"The type for bytes fields. Can be "String", "Array"
--defaultsbooleanfalseOutput default values for omitted fields
--arraysbooleanfalseOutput default values for omitted repeated fields even if --defaults is not set
--objectsbooleanfalseOutput default values for omitted message fields even if --defaults is not set
--oneofsbooleanfalseOutput virtual oneof fields set to the present field's name
--jsonbooleanfalseRepresent Infinity and NaN as strings in float fields. Also decode google.protobuf.Any automatically
--includeCommentsbooleanfalseGenerate doc comments from comments in the original files
-I, --includeDirsarray-Directories to search for included files
-O, --outDirstringrequiredDirectory to output generated files
--grpcLibstring-The gRPC implementation library (affects generated types)
--inputTemplatestring"%s"Template for mapping input or "permissive" type names
--outputTemplatestring"%s__Output"Template for mapping output or "restricted" type names
--inputBrandedbooleanfalseOutput property for branded type for "permissive" types
--outputBrandedbooleanfalseOutput property for branded type for "restricted" types
--targetFileExtensionstring".ts"File extension for generated files
--importFileExtensionstring""File extension for import specifiers in generated code

Common Usage Examples

Basic Type Generation

# Generate basic TypeScript types
proto-loader-gen-types --outDir=./types proto/service.proto

# Multiple proto files
proto-loader-gen-types --outDir=./types proto/*.proto

gRPC-Compatible Types

# Generate types compatible with @grpc/grpc-js
proto-loader-gen-types \
  --longs=String \
  --enums=String \
  --defaults \
  --oneofs \
  --grpcLib=@grpc/grpc-js \
  --outDir=./proto \
  proto/*.proto

Advanced Configuration

# Generate with custom templates and comments
proto-loader-gen-types \
  --longs=String \
  --enums=String \
  --defaults \
  --oneofs \
  --includeComments \
  --inputTemplate="I%s" \
  --outputTemplate="O%s" \
  --grpcLib=@grpc/grpc-js \
  -I ./proto \
  -I ./external-proto \
  --outDir=./generated \
  proto/service.proto

Generated Type Structure

The CLI tool generates several types of TypeScript definitions:

Service Types

// Generated service interface
export interface MyServiceHandlers extends grpc.UntypedServiceImplementation {
  myMethod: grpc.handleUnaryCall<MyRequest, MyResponse>;
  myStreamMethod: grpc.handleServerStreamingCall<MyRequest, MyResponse>;
}

// Generated service definition
export const MyServiceService: grpc.ServiceDefinition<MyServiceHandlers>;

Message Types

// Input type (permissive, for creating messages)
export interface MyMessage {
  field1?: string;
  field2?: number;
  optionalField?: string;
}

// Output type (with defaults applied, for receiving messages)
export interface MyMessage__Output {
  field1: string;
  field2: number;
  optionalField: string;
}

Enum Types

// Enum as const object
export const MyEnum = {
  VALUE1: 'VALUE1',
  VALUE2: 'VALUE2',
} as const;

// Enum type
export type MyEnum = 'VALUE1' | 'VALUE2';
export type MyEnum__Output = typeof MyEnum[keyof typeof MyEnum];

Package Root Type

// Complete package type combining all definitions
export interface ProtoGrpcType {
  mypackage: {
    MyService: SubtypeConstructor<typeof grpc.Client, MyServiceHandlers>;
    MyMessage: MessageTypeDefinition;
    MyEnum: EnumTypeDefinition;
  };
}

Integration with Code

Server Implementation

import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';
import type { ProtoGrpcType } from './proto/service';
import type { MyServiceHandlers } from './proto/mypackage/MyService';

const packageDefinition = protoLoader.loadSync('./proto/service.proto');
const proto = (grpc.loadPackageDefinition(
  packageDefinition
) as unknown) as ProtoGrpcType;

const server = new grpc.Server();

const serviceImplementation: MyServiceHandlers = {
  myMethod: (call, callback) => {
    // call.request is strongly typed
    const response = { message: `Hello ${call.request.name}` };
    callback(null, response);
  },
};

server.addService(proto.mypackage.MyService.service, serviceImplementation);

Client Usage

import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';
import type { ProtoGrpcType } from './proto/service';
import type { MyServiceClient } from './proto/mypackage/MyService';

const packageDefinition = protoLoader.loadSync('./proto/service.proto');
const proto = (grpc.loadPackageDefinition(
  packageDefinition
) as unknown) as ProtoGrpcType;

const client = new proto.mypackage.MyService(
  'localhost:50051',
  grpc.credentials.createInsecure()
) as MyServiceClient;

// Type-safe method calls
client.myMethod({ name: 'World' }, (error, response) => {
  if (!error) {
    // response is strongly typed
    console.log(response.message);
  }
});

Custom Templates

The CLI tool supports custom naming templates for generated types:

Input/Output Templates

# Use I/O prefixes
proto-loader-gen-types \
  --inputTemplate="I%s" \
  --outputTemplate="O%s" \
  --outDir=./types \
  service.proto

This generates:

// Input types (permissive)
export interface IMyMessage {
  field?: string;
}

// Output types (with defaults)
export interface OMyMessage {
  field: string;
}

Branded Types

# Generate branded types for additional type safety
proto-loader-gen-types \
  --inputBranded \
  --outputBranded \
  --outDir=./types \
  service.proto

Error Handling

The CLI tool provides detailed error messages for common issues:

  • Proto file not found: Clear file path errors
  • Parse errors: Line-by-line syntax error reporting
  • Import resolution: Missing import file reporting
  • Output directory: Permission and path validation

Example Error Output:

Error: Proto file not found: ./proto/service.proto
  at loadProtos (/path/to/proto-loader-gen-types.js:123:45)
  
Error: Parse error in service.proto:15:3
  syntax error: expected ';' after field definition

Build Integration

Package.json Scripts

{
  "scripts": {
    "proto:gen": "proto-loader-gen-types --longs=String --enums=String --defaults --oneofs --grpcLib=@grpc/grpc-js --outDir=src/proto proto/*.proto",
    "proto:watch": "chokidar 'proto/*.proto' -c 'npm run proto:gen'",
    "prebuild": "npm run proto:gen"
  }
}

Build Tools Integration

// webpack.config.js - Generate types before build
const { execSync } = require('child_process');

module.exports = {
  // ... other config
  plugins: [
    {
      apply: (compiler) => {
        compiler.hooks.beforeCompile.tap('ProtoGen', () => {
          execSync('npm run proto:gen', { stdio: 'inherit' });
        });
      }
    }
  ]
};

docs

cli-tool.md

index.md

proto-loading.md

type-definitions.md

tile.json