-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit ead6908
Showing
10 changed files
with
624 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
root = true | ||
|
||
[*] | ||
indent_style = space | ||
indent_size = 2 | ||
end_of_line = lf | ||
charset = utf-8 | ||
trim_trailing_whitespace = true | ||
insert_final_newline = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
{ | ||
"extends": [ | ||
"plugin:@typescript-eslint/recommended" | ||
], | ||
"env": { | ||
"node": true, | ||
"es6": true | ||
}, | ||
"parser": "@typescript-eslint/parser", | ||
"parserOptions": { | ||
"sourceType": "module" | ||
}, | ||
"plugins": [ | ||
"@typescript-eslint" | ||
], | ||
"rules": { | ||
"@typescript-eslint/indent": [ | ||
"error", | ||
2 | ||
], | ||
"@typescript-eslint/no-use-before-define": 0, | ||
"@typescript-eslint/prefer-interface": 0, | ||
"linebreak-style": [ | ||
"error", | ||
"unix" | ||
], | ||
"quotes": [ | ||
"error", | ||
"single" | ||
], | ||
"semi": [ | ||
"error", | ||
"always" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
node_modules | ||
build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package-lock=false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
language: node_js | ||
node_js: | ||
- '11' | ||
- '10' | ||
- '8' | ||
- '6' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
# pb-util | ||
|
||
> Utilities for working with common protobuf types. | ||
## Installing | ||
|
||
```sh | ||
$ npm i --save pb-util | ||
``` | ||
|
||
## API | ||
|
||
### value.encode(val) | ||
|
||
Encodes a JSON value into a [`google.protobuf.Value`][pb-value]. | ||
|
||
#### val | ||
|
||
Type: `string` `number` `boolean` `null` `object` `array` | ||
|
||
```js | ||
const {value} = require('pb-util'); | ||
|
||
const stringValue = value.encode('hello!'); | ||
// => { | ||
// kind: 'stringValue', | ||
// stringValue: 'hello!' | ||
// } | ||
``` | ||
|
||
### value.decode(protoValue) | ||
|
||
Decodes a [`google.protobuf.Value`][pb-value] into a JSON value. | ||
|
||
#### protoValue | ||
|
||
Type: [`google.protobuf.Value`][pb-value] | ||
|
||
```js | ||
const {value} = require('pb-util'); | ||
|
||
const str = value.decode({ | ||
kind: 'stringValue', | ||
stringValue: 'beep boop' | ||
}); | ||
// => 'beep boop' | ||
``` | ||
|
||
### struct.encode(json) | ||
|
||
Encodes a JSON object into a [`google.protobuf.Struct`][pb-struct]. | ||
|
||
#### json | ||
|
||
Type: `object` | ||
|
||
```js | ||
const {struct} = require('pb-util'); | ||
|
||
const structValue = struct.encode({foo: 'bar'}); | ||
// => { | ||
// fields: { | ||
// foo: { | ||
// kind: 'stringValue', | ||
// stringValue: 'bar' | ||
// } | ||
// } | ||
// } | ||
``` | ||
|
||
### struct.decode(structValue) | ||
|
||
Decodes a [`google.protobuf.Struct`][pb-struct] into a JSON object. | ||
|
||
#### structValue | ||
|
||
Type: [`google.protobuf.ListValue`][pb-list] | ||
|
||
```js | ||
const {struct} = require('pb-util'); | ||
|
||
const obj = struct.decode({ | ||
fields: { | ||
foo: { | ||
kind: 'stringValue', | ||
stringValue: 'bar' | ||
}, | ||
yes: { | ||
kind: 'boolValue', | ||
boolValue: true | ||
} | ||
} | ||
}); | ||
// => { | ||
// foo: 'bar', | ||
// yes: true | ||
// } | ||
``` | ||
|
||
### list.encode(array) | ||
|
||
Encodes an array of JSON values into a [`google.protobuf.ListValue`][pb-list]. | ||
|
||
#### array | ||
|
||
Type: `array` | ||
|
||
```js | ||
const {list} = require('pb-util'); | ||
|
||
const listValue = list.encode(['foo', 'bar']); | ||
// => { | ||
// values: [ | ||
// { | ||
// kind: 'stringValue', | ||
// stringValue: 'foo' | ||
// }, | ||
// { | ||
// kind: 'stringValue', | ||
// stringValue: 'bar' | ||
// } | ||
// ] | ||
// } | ||
``` | ||
|
||
### list.decode(listValue) | ||
|
||
Decodes a [`google.protobuf.ListValue`][pb-list] into an array of JSON values. | ||
|
||
#### listValue | ||
|
||
Type: [`google.protobuf.ListValue`][pb-list] | ||
|
||
```js | ||
const {list} = require('pb-util'); | ||
|
||
const arr = list.decode({ | ||
values: [ | ||
{ | ||
kind: 'stringValue', | ||
stringValue: 'foo' | ||
}, | ||
{ | ||
kind: 'numberValue', | ||
numberValue: 10 | ||
} | ||
] | ||
}); | ||
// => ['foo', 10] | ||
``` | ||
|
||
## License | ||
|
||
ISC | ||
|
||
[pb-value]: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Value | ||
[pb-list]: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#listvalue | ||
[pb-struct]: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#struct |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
/** | ||
* Matches a JSON object. | ||
*/ | ||
export type JsonObject = {[key: string]: JsonValue}; | ||
|
||
/** | ||
* Matches a JSON array. | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-empty-interface | ||
export interface JsonArray extends Array<JsonValue> {} | ||
|
||
/** | ||
* Matches any valid JSON value. | ||
*/ | ||
export type JsonValue = string|number|boolean|null|JsonObject|JsonArray; | ||
|
||
/** | ||
* @typedef {Object} Value | ||
* @property {string} kind The kind of value. Valid values for this fields are | ||
* - `nullValue` | ||
* - `numberValue` | ||
* - `stringValue` | ||
* - `boolValue` | ||
* - `structValue` | ||
* - `listValue` | ||
* @property {number} [nullValue] Represents a null value, actual field value | ||
* should be `0`. | ||
* @property {number} [numberValue] Represents a number. | ||
* @property {string} [stringValue] Represents a string. | ||
* @property {boolean} [boolValue] Represents a boolean. | ||
* @property {Struct} [structValue] Represents an object. | ||
* @property {ListValue} [listValue] Represents an array of values. | ||
*/ | ||
export interface Value { | ||
kind?: string; | ||
nullValue?: number; | ||
numberValue?: number; | ||
stringValue?: string; | ||
boolValue?: boolean; | ||
structValue?: Struct; | ||
listValue?: ListValue; | ||
} | ||
|
||
/** | ||
* @typedef {Object} Struct | ||
* @property {Object.<string, Value>} fields The struct fields. | ||
*/ | ||
export interface Struct { | ||
fields?: {[key: string]: Value}; | ||
} | ||
|
||
/** | ||
* @typedef {Object} ListValue | ||
* @property {Value[]} values The list values. | ||
*/ | ||
export interface ListValue { | ||
values?: Value[]; | ||
} | ||
|
||
const toString = Object.prototype.toString; | ||
|
||
const encoders = { | ||
[typeOf({})]: v => wrap('structValue', struct.encode(v)), | ||
[typeOf([])]: v => wrap('listValue', list.encode(v)), | ||
[typeOf(0)]: v => wrap('numberValue', v), | ||
[typeOf('')]: v => wrap('stringValue', v), | ||
[typeOf(true)]: v => wrap('boolValue', v), | ||
[typeOf(null)]: () => wrap('nullValue', 0) | ||
}; | ||
|
||
function typeOf(value: JsonValue): string { | ||
return toString.call(value); | ||
} | ||
|
||
function wrap(kind: keyof Value, value): Value { | ||
return {kind, [kind]: value}; | ||
} | ||
|
||
/** | ||
* Used to encode/decode {@link Value} objects. | ||
*/ | ||
export const value = { | ||
/** | ||
* Encodes a JSON value into a protobuf {@link Value}. | ||
* | ||
* @param {*} value The JSON value. | ||
* @returns {Value} | ||
*/ | ||
encode(value: JsonValue): Value { | ||
const type = typeOf(value); | ||
const encoder = encoders[type]; | ||
if (typeof encoder !== 'function') { | ||
throw new TypeError(`Unable to infer type for "${value}".`); | ||
} | ||
return encoder(value); | ||
}, | ||
/** | ||
* Decodes a protobuf {@link Value} into a JSON value. | ||
* | ||
* @param {Value} value the protobuf value. | ||
* @returns {*} | ||
*/ | ||
decode(value: Value): JsonValue { | ||
if (value.listValue) { | ||
return list.decode(value.listValue); | ||
} | ||
if (value.structValue) { | ||
return struct.decode(value.structValue); | ||
} | ||
if (typeof value.nullValue !== 'undefined') { | ||
return null; | ||
} | ||
return value[value.kind] as JsonValue; | ||
} | ||
}; | ||
|
||
/** | ||
* Used to encode/decode {@link Struct} objects. | ||
*/ | ||
export const struct = { | ||
/** | ||
* Encodes a JSON object into a protobuf {@link Struct}. | ||
* | ||
* @param {Object.<string, *>} value the JSON object. | ||
* @returns {Struct} | ||
*/ | ||
encode(json: JsonObject): Struct { | ||
const fields = {}; | ||
Object.keys(json).forEach(key => { | ||
fields[key] = value.encode(json[key]); | ||
}); | ||
return {fields}; | ||
}, | ||
/** | ||
* Decodes a protobuf {@link Struct} into a JSON object. | ||
* | ||
* @param {Struct} struct the protobuf struct. | ||
* @returns {Object.<string, *>} | ||
*/ | ||
decode({fields}: Struct): JsonObject { | ||
const json = {}; | ||
Object.keys(fields).forEach(key => { | ||
json[key] = value.decode(fields[key]); | ||
}); | ||
return json; | ||
} | ||
}; | ||
|
||
/** | ||
* Used to encode/decode {@link ListValue} objects. | ||
*/ | ||
export const list = { | ||
/** | ||
* Encodes an array of JSON values into a protobuf {@link ListValue}. | ||
* | ||
* @param {Array.<*>} values the JSON values. | ||
* @returns {ListValue} | ||
*/ | ||
encode(values: JsonArray): ListValue { | ||
return { | ||
values: values.map(value.encode) | ||
}; | ||
}, | ||
/** | ||
* Decodes a protobuf {@link ListValue} into an array of JSON values. | ||
* | ||
* @param {ListValue} list the protobuf list value. | ||
* @returns {Array.<*>} | ||
*/ | ||
decode({values}: ListValue): JsonArray { | ||
return values.map(value.decode); | ||
} | ||
}; |
Oops, something went wrong.