Skip to content

Commit

Permalink
y halo thar
Browse files Browse the repository at this point in the history
  • Loading branch information
callmehiphop committed Mar 27, 2019
0 parents commit ead6908
Show file tree
Hide file tree
Showing 10 changed files with 624 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .editorconfig
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
36 changes: 36 additions & 0 deletions .eslintrc.json
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"
]
}
}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
build
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
language: node_js
node_js:
- '11'
- '10'
- '8'
- '6'
158 changes: 158 additions & 0 deletions README.md
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
173 changes: 173 additions & 0 deletions index.ts
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);
}
};
Loading

0 comments on commit ead6908

Please sign in to comment.