grpc-web-from-object
Advanced tools
Comparing version 2.2.0 to 2.3.0
# Changelog | ||
## [2.3.0](https://github.com/infodusha/grpc-web-from-object/compare/v2.2.0...v2.3.0) (2023-03-06) | ||
### Features | ||
* createFromObjectRecursive ([7a7de77](https://github.com/infodusha/grpc-web-from-object/commit/7a7de7764342b963be327d93a78fc9766c1dcc16)) | ||
* support for maps ([098163e](https://github.com/infodusha/grpc-web-from-object/commit/098163ec9b3bdc286a539c894ebaac9ea8b61e4a)) | ||
* tsd ([d12112d](https://github.com/infodusha/grpc-web-from-object/commit/d12112dd8ca0dda2501b3d5abaf1f2e1f5df7f9b)) | ||
## [2.2.0](https://github.com/infodusha/grpc-web-from-object/compare/v2.1.2...v2.2.0) (2023-03-04) | ||
@@ -4,0 +13,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { Message } from "google-protobuf"; | ||
import { Message, Map as ProtobufMap } from "google-protobuf"; | ||
export type FromObject<T extends Message> = (data: AsObject<T>) => T; | ||
@@ -6,5 +6,6 @@ type MessageConstructor<T extends Message> = new () => T; | ||
type MessageFnReturnValue<T extends Message, Key extends keyof T> = T[Key] extends (...args: unknown[]) => infer R ? R : never; | ||
type IsProtobufMap<T> = T extends ProtobufMap<unknown, infer X> ? X : T; | ||
type IsMessageOrMessageArray<T> = T extends Array<infer R> ? IsMessageOrMessageArray<R> : T extends Message | undefined ? Exclude<T, undefined> : never; | ||
type GetMessageKeys<T extends Message> = { | ||
[K in keyof T]: K extends `get${string}` ? IsMessageOrMessageArray<MessageFnReturnValue<T, K>> extends never ? never : K : never; | ||
[K in keyof T]: K extends `get${string}` ? IsMessageOrMessageArray<IsProtobufMap<MessageFnReturnValue<T, K>>> extends never ? never : K : never; | ||
}[keyof T]; | ||
@@ -14,3 +15,3 @@ type MessageToObjectKey<T extends string> = T extends `get${infer R}` ? Uncapitalize<R> : never; | ||
type MessageFactories<T extends Message> = { | ||
[K in MessageToObjectKey<GetMessageKeys<T>>]: FromObject<IsMessageOrMessageArray<MessageFnReturnValue<T, AsObjectToMessageKey<K> extends keyof T ? AsObjectToMessageKey<K> : never>>>; | ||
[K in MessageToObjectKey<GetMessageKeys<T>>]: FromObject<IsMessageOrMessageArray<IsProtobufMap<MessageFnReturnValue<T, AsObjectToMessageKey<K> extends keyof T ? AsObjectToMessageKey<K> : never>>>>; | ||
}; | ||
@@ -21,2 +22,3 @@ type EmptyFactory<T extends Message> = GetMessageKeys<T> extends never ? T : never; | ||
export declare function createFromObject<T extends Message>(MessageType: MessageConstructor<NonEmptyFactory<T>>, factories: MessageFactories<T>): FromObject<T>; | ||
export declare function createFromObjectRecursive<T extends Message>(MessageType: MessageConstructor<NonEmptyFactory<T>>): FromObject<T>; | ||
export {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createFromObject = void 0; | ||
exports.createFromObjectRecursive = exports.createFromObject = void 0; | ||
const google_protobuf_1 = require("google-protobuf"); | ||
const recursiveFactories = new WeakMap(); | ||
const SETTER_PREFIX = 'set'; | ||
const GETTER_PREFIX = 'get'; | ||
const CLEAR_PREFIX = 'clear'; | ||
function createFromObject(MessageType, factories) { | ||
const allFactories = factories ?? {}; | ||
const recursiveFactory = recursiveFactories.get(MessageType); | ||
if (recursiveFactory) { | ||
Object.assign(recursiveFactory, allFactories); | ||
} | ||
return (data) => { | ||
@@ -12,2 +19,15 @@ const instance = new MessageType(); | ||
for (const [prop, value] of Object.entries(filterExtraProps(instance, data))) { | ||
if (Array.isArray(value) && isProtobufMap(instance, prop)) { | ||
const mapMethod = getMethod(prop, GETTER_PREFIX); | ||
const map = callMethod(instance, mapMethod); | ||
for (const [k, v] of value) { | ||
if (!isObject(v, prop)) { | ||
map.set(k, v); | ||
continue; | ||
} | ||
validateMissingFactory(allFactories, prop); | ||
map.set(k, callMethod(allFactories, prop, v)); | ||
} | ||
continue; | ||
} | ||
const result = getResult(allFactories, prop, value); | ||
@@ -46,6 +66,15 @@ const setter = getMethod(prop); | ||
function getInstanceProps(instance) { | ||
return Object.keys(Object.getPrototypeOf(instance)) | ||
const keys = Object.keys(Object.getPrototypeOf(instance)); | ||
const setters = keys | ||
.filter((key) => key.startsWith(SETTER_PREFIX)) | ||
.map(key => getProp(key)); | ||
const maps = keys | ||
.filter((key) => key.startsWith(CLEAR_PREFIX)) | ||
.map(key => getProp(key, CLEAR_PREFIX)) | ||
.filter(prop => isProtobufMap(instance, prop)); | ||
return [...setters, ...maps]; | ||
} | ||
function isProtobufMap(instance, prop) { | ||
return callMethod(instance, getMethod(prop, GETTER_PREFIX)) instanceof google_protobuf_1.Map; | ||
} | ||
function isOptional(instance, prop) { | ||
@@ -88,1 +117,18 @@ const clearMethod = getMethod(prop, CLEAR_PREFIX); | ||
} | ||
function createFromObjectRecursive(MessageType) { | ||
const factories = {}; | ||
recursiveFactories.set(MessageType, factories); | ||
const propertyDescriptors = getInstanceProps(new MessageType()) | ||
.reduce((acc, prop) => ({ | ||
...acc, | ||
[prop]: { | ||
get() { | ||
validateMissingFactory(factories, prop); | ||
return factories[prop]; | ||
}, | ||
}, | ||
}), {}); | ||
const dynamicFactories = Object.defineProperties({}, propertyDescriptors); | ||
return createFromObject(MessageType, dynamicFactories); | ||
} | ||
exports.createFromObjectRecursive = createFromObjectRecursive; |
{ | ||
"name": "grpc-web-from-object", | ||
"version": "2.2.0", | ||
"version": "2.3.0", | ||
"description": "fromObject method for grpc-web", | ||
@@ -8,3 +8,5 @@ "main": "lib/index.js", | ||
"build": "tsc", | ||
"test": "jest", | ||
"test": "npm run test:unit && npm run test:types", | ||
"test:unit": "jest", | ||
"test:types": "npm run build && npx tsd -f ./__tests__/index.test-d.ts -t ./lib/index.d.ts", | ||
"lint": "eslint .", | ||
@@ -49,2 +51,3 @@ "generate": "sh ./__tests__/test-data/generate.sh" | ||
"ts-jest": "^29.0.5", | ||
"tsd": "^0.26.0", | ||
"typescript": "^4.9.4" | ||
@@ -51,0 +54,0 @@ }, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
24437
152
10