Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ts-proto

Package Overview
Dependencies
Maintainers
1
Versions
359
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ts-proto - npm Package Compare versions

Comparing version 1.2.2 to 1.3.0

68

build/main.js

@@ -40,2 +40,3 @@ "use strict";

.addHashEntry(generateFromJson(typeMap, fullName, message))
.addHashEntry(generateFromPartial(typeMap, fullName, message))
.addHashEntry(generateToJson(typeMap, fullName, message))

@@ -62,2 +63,3 @@ .endHash()

file = addLongUtilityMethod(file);
file = addDeepPartialType(file);
let hasAnyTimestamps = false;

@@ -82,2 +84,18 @@ visit(fileDesc, (_, messageType) => {

}
function addDeepPartialType(file) {
return file.addCode(ts_poet_1.CodeBlock.empty()
.add('export type DeepPartial<T> = {%>\n')
.add('[P in keyof T]?: T[P] extends Array<infer U>\n')
.add('? Array<DeepPartial<U>>\n')
.add(': T[P] extends ReadonlyArray<infer U>\n')
.add('? ReadonlyArray<DeepPartial<U>>\n')
.add(': T[P] extends Date | Function | Uint8Array | undefined\n')
.add('? T[P]\n')
.add(': T[P] extends infer U | undefined\n')
.add('? DeepPartial<U>\n')
.add(': T[P] extends object\n')
.add('? DeepPartial<T[P]>\n')
.add(': T[P]\n%<')
.add('};'));
}
function addTimestampMethods(file) {

@@ -456,2 +474,52 @@ const timestampType = 'Timestamp@./google/protobuf/timestamp';

}
function generateFromPartial(typeMap, fullName, messageDesc) {
// create the basic function declaration
let func = ts_poet_1.FunctionSpec.create('fromPartial')
.addParameter('object', `DeepPartial<${fullName}>`)
.returns(fullName);
func = func.addStatement('const message = Object.create(base%L) as %L', fullName, fullName);
// initialize all lists
messageDesc.field.filter(types_1.isRepeated).forEach(field => {
const value = types_1.isMapType(typeMap, messageDesc, field) ? '{}' : '[]';
func = func.addStatement('message.%L = %L', snakeToCamel(field.name), value);
});
// add a check for each incoming field
messageDesc.field.forEach(field => {
const fieldName = snakeToCamel(field.name);
const readSnippet = (from) => {
if (types_1.isEnum(field) || types_1.isPrimitive(field) || types_1.isTimestamp(field) || types_1.isValueType(field)) {
return ts_poet_1.CodeBlock.of(from);
}
else if (types_1.isMessage(field)) {
return ts_poet_1.CodeBlock.of('%T.fromPartial(%L)', types_1.basicTypeName(typeMap, field), from);
}
else {
throw new Error(`Unhandled field ${field}`);
}
};
// and then use the snippet to handle repeated fields if necessary
func = func.beginControlFlow('if (object.%L)', fieldName);
if (types_1.isRepeated(field)) {
if (types_1.isMapType(typeMap, messageDesc, field)) {
func = func
.addStatement(`const entry = %L`, readSnippet(`object.${fieldName}`))
.beginControlFlow('if (entry.value)')
.addStatement('message.%L[entry.key] = entry.value', fieldName)
.endControlFlow();
}
else {
func = func
.beginControlFlow('for (const e of object.%L)', fieldName)
.addStatement(`message.%L.push(%L)`, fieldName, readSnippet('e'))
.endControlFlow();
}
}
else {
func = func.addStatement(`message.%L = %L`, fieldName, readSnippet(`object.${fieldName}`));
}
func = func.endControlFlow();
});
// and then wrap up the switch/while/return
return func.addStatement('return message');
}
function generateService(typeMap, fileDesc, serviceDesc) {

@@ -458,0 +526,0 @@ let service = ts_poet_1.InterfaceSpec.create(serviceDesc.name).addModifiers(ts_poet_1.Modifier.EXPORT);

2

build/types.js

@@ -231,3 +231,3 @@ "use strict";

const mappedTypes = {
'.google.protobuf.Timestamp': ts_poet_1.TypeNames.unionType(ts_poet_1.TypeNames.DATE, ts_poet_1.TypeNames.UNDEFINED)
'.google.protobuf.Timestamp': ts_poet_1.TypeNames.DATE
};

@@ -234,0 +234,0 @@ function isTimestamp(field) {

{
"name": "ts-proto",
"version": "1.2.2",
"version": "1.3.0",
"description": "",

@@ -25,5 +25,5 @@ "main": "build/plugin.js",

"prettier": "^1.16.4",
"ts-jest": "^24.0.1",
"ts-node": "^8.0.3",
"typescript": "^3.4.1"
"ts-jest": "^24.0.2",
"ts-node": "^8.3.0",
"typescript": "^3.5.2"
},

@@ -30,0 +30,0 @@ "dependencies": {

@@ -84,2 +84,3 @@ import {

.addHashEntry(generateFromJson(typeMap, fullName, message))
.addHashEntry(generateFromPartial(typeMap, fullName, message))
.addHashEntry(generateToJson(typeMap, fullName, message))

@@ -111,2 +112,3 @@ .endHash()

file = addLongUtilityMethod(file);
file = addDeepPartialType(file);

@@ -138,2 +140,21 @@ let hasAnyTimestamps = false;

function addDeepPartialType(file: FileSpec): FileSpec {
return file.addCode(
CodeBlock.empty()
.add('export type DeepPartial<T> = {%>\n')
.add('[P in keyof T]?: T[P] extends Array<infer U>\n')
.add('? Array<DeepPartial<U>>\n')
.add(': T[P] extends ReadonlyArray<infer U>\n')
.add('? ReadonlyArray<DeepPartial<U>>\n')
.add(': T[P] extends Date | Function | Uint8Array | undefined\n')
.add('? T[P]\n')
.add(': T[P] extends infer U | undefined\n')
.add('? DeepPartial<U>\n')
.add(': T[P] extends object\n')
.add('? DeepPartial<T[P]>\n')
.add(': T[P]\n%<')
.add('};')
);
}
function addTimestampMethods(file: FileSpec): FileSpec {

@@ -559,2 +580,54 @@ const timestampType = 'Timestamp@./google/protobuf/timestamp';

function generateFromPartial(typeMap: TypeMap, fullName: string, messageDesc: DescriptorProto): FunctionSpec {
// create the basic function declaration
let func = FunctionSpec.create('fromPartial')
.addParameter('object', `DeepPartial<${fullName}>`)
.returns(fullName);
func = func.addStatement('const message = Object.create(base%L) as %L', fullName, fullName);
// initialize all lists
messageDesc.field.filter(isRepeated).forEach(field => {
const value = isMapType(typeMap, messageDesc, field) ? '{}' : '[]';
func = func.addStatement('message.%L = %L', snakeToCamel(field.name), value);
});
// add a check for each incoming field
messageDesc.field.forEach(field => {
const fieldName = snakeToCamel(field.name);
const readSnippet = (from: string): CodeBlock => {
if (isEnum(field) || isPrimitive(field) || isTimestamp(field) || isValueType(field)) {
return CodeBlock.of(from);
} else if (isMessage(field)) {
return CodeBlock.of('%T.fromPartial(%L)', basicTypeName(typeMap, field), from);
} else {
throw new Error(`Unhandled field ${field}`);
}
};
// and then use the snippet to handle repeated fields if necessary
func = func.beginControlFlow('if (object.%L)', fieldName);
if (isRepeated(field)) {
if (isMapType(typeMap, messageDesc, field)) {
func = func
.addStatement(`const entry = %L`, readSnippet(`object.${fieldName}`))
.beginControlFlow('if (entry.value)')
.addStatement('message.%L[entry.key] = entry.value', fieldName)
.endControlFlow();
} else {
func = func
.beginControlFlow('for (const e of object.%L)', fieldName)
.addStatement(`message.%L.push(%L)`, fieldName, readSnippet('e'))
.endControlFlow();
}
} else {
func = func.addStatement(`message.%L = %L`, fieldName, readSnippet(`object.${fieldName}`));
}
func = func.endControlFlow();
});
// and then wrap up the switch/while/return
return func.addStatement('return message');
}
function generateService(

@@ -651,3 +724,3 @@ typeMap: TypeMap,

const inputTypeDesc = inputType[2] as DescriptorProto;
const outputTypeDesc= outputType[2] as DescriptorProto;
const outputTypeDesc = outputType[2] as DescriptorProto;
if (hasSingleRepeatedField(inputTypeDesc) && hasSingleRepeatedField(outputTypeDesc)) {

@@ -654,0 +727,0 @@ const singleMethodName = methodDesc.name.replace('Batch', 'Get');

@@ -237,3 +237,3 @@ import { google } from '../build/pbjs';

const mappedTypes: { [key: string]: TypeName } = {
'.google.protobuf.Timestamp': TypeNames.unionType(TypeNames.DATE, TypeNames.UNDEFINED)
'.google.protobuf.Timestamp': TypeNames.DATE
};

@@ -240,0 +240,0 @@

@@ -0,4 +1,8 @@

import { google } from '../build/pbjs';
import { messageToTypeName } from '../src/types';
import { TypeNames } from 'ts-poet';
import DescriptorProto = google.protobuf.DescriptorProto;
const fakeProto = (undefined as any) as DescriptorProto;
describe('main', () => {

@@ -8,4 +12,4 @@ describe('messageToTypeName', () => {

// these are not very useful tests now that this is just a map lookup
const typeMap = new Map<string, [string, string]>();
typeMap.set('namespace.Message', ['namespace', 'Message']);
const typeMap = new Map<string, [string, string, DescriptorProto]>();
typeMap.set('namespace.Message', ['namespace', 'Message', fakeProto]);
expect(messageToTypeName(typeMap, '.namespace.Message')).toEqual(TypeNames.anyType('Message@./namespace'));

@@ -15,4 +19,4 @@ });

it('handles nested messages', () => {
const typeMap = new Map<string, [string, string]>();
typeMap.set('namespace.Message.Inner', ['namespace', 'Message_Inner']);
const typeMap = new Map<string, [string, string, DescriptorProto]>();
typeMap.set('namespace.Message.Inner', ['namespace', 'Message_Inner', fakeProto]);
expect(messageToTypeName(typeMap, '.namespace.Message.Inner')).toEqual(

@@ -24,3 +28,3 @@ TypeNames.anyType('Message_Inner@./namespace')

it('handles value types', () => {
const typeMap = new Map<string, [string, string]>();
const typeMap = new Map<string, [string, string, DescriptorProto]>();
expect(messageToTypeName(typeMap, '.google.protobuf.StringValue')).toEqual(

@@ -27,0 +31,0 @@ TypeNames.unionType(TypeNames.STRING, TypeNames.UNDEFINED)

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc