Permalink
Browse files

New: Implemented stubs for long.js / node buffers to be used where ei…

…ther one isn't wanted, see #718
  • Loading branch information...
dcodeIO committed Mar 23, 2017
1 parent a06691f commit c04d4a5ab8f91899bd3e1b17fe4407370ef8abb7
@@ -77,7 +77,7 @@ Where bundle size is a factor, there is a suitable distribution for each of thes
| light | 15.5kb | [dist/light][dist-light] | `require("protobufjs/light")` | All features except tokenizer, parser and bundled common types. Works with JSON definitions, pure reflection and static code.
| minimal | 6.0kb+ | [dist/minimal][dist-minimal] | `require("protobufjs/minimal")` | Just enough to run static code. No reflection.
In case of doubt you can just use the full library.
In case of doubt it is safe to just use the full library.
[dist-full]: https://github.com/dcodeIO/protobuf.js/tree/master/dist
[dist-light]: https://github.com/dcodeIO/protobuf.js/tree/master/dist/light
@@ -88,7 +88,7 @@ Usage
Each message type provides a set of methods with each method doing just one thing. This allows to avoid unnecessary operations where [performance](#performance) is a concern but also forces a user to perform verification explicitly where necessary - for example when dealing with user input.
Note that **Message** refers to any message type below.
Note that **Message** below refers to any message type. See the next section for the definition of a [valid message](#valid-message).
* **Message.verify**(message: `Object`): `null|string`<br />
explicitly performs verification prior to encoding a plain object. Instead of throwing, it returns the error message as a string, if any.
@@ -160,29 +160,30 @@ Note that **Message** refers to any message type below.
See also: [ConversionOptions](http://dcode.io/protobuf.js/global.html#ConversionOptions)
**What is a valid message?**
### Valid message
A valid message is an object not missing any required fields and exclusively using JS types for its fields that are understood by the wire format writer.
* Calling `Message.verify` with a valid message returns `null` and otherwise the error as a string.
* Calling `Message.create` or `Message.encode` with any object assumes valid types.
* Calling `Message.verify` with any object returns `null` if the object can be encoded as-is and otherwise the error as a string.
* Calling `Message.create` or `Message.encode` must be called with a valid message.
* Calling `Message.fromObject` with any object naively converts all values to the optimal JS type.
| Type | Expected JS type (create) | Naive conversion (fromObject)
|--------|-----------------|-------------------
| int32<br />uint32<br />sint32<br />fixed32<br />sfixed32 | `Number` (32 bit integer) | `value | 0`<br /> `value >>> 0`
| int64<br />uint64<br />sint64<br />fixed64<br />sfixed64 | `Long`-like (optimal)<br />`Number` (53 bit integer) | `Long.fromValue(value)`<br />`parseInt(value, 10)` without long.js
| Field type | Expected JS type (create, encode) | Naive conversion (fromObject)
|------------|-----------------------------------|------------------------------
| s-/u-/int32<br />s-/fixed32 | `Number` (32 bit integer) | `value | 0` if signed<br /> `value >>> 0` if unsigned
| s-/u-/int64<br />s-/fixed64 | `Long`-like (optimal)<br />`Number` (53 bit integer) | `Long.fromValue(value)` with long.js<br />`parseInt(value, 10)` otherwise
| float<br />double | `Number` | `Number(value)`
| bool | `Boolean` | `Boolean(value)`
| string | `String` | `String(value)`
| bytes | `Uint8Array` (optimal)<br />`Buffer` (optimal)<br />`Array.<Number>` (8 bit integers)<br />`String` (base64) | `base64.decode(value)` if a String<br />`Object` with non-zero `.length` is kept
| bytes | `Uint8Array` (optimal)<br />`Buffer` (optimal under node)<br />`Array.<Number>` (8 bit integers)<br />`String` (base64) | `base64.decode(value)` if a String<br />`Object` with non-zero `.length` is kept
| enum | `Number` (32 bit integer) | Looks up the numeric id if a string
| message | Valid message | `Message.fromObject(value)`
* Explicit `undefined` and `null` are considered as not set when optional.
* Repeated fields are `Array.<T>`.
* Map fields are `Object.<string,T>` with the key being the string representation of the respective value or an 8 characters long binary hash string for Long-likes.
* Map fields are `Object.<string,T>` with the key being the string representation of the respective value or an 8 characters long binary hash string for `Long`-likes.
* `String` refers to both objects and values while `Number` refers to values only.
* Types marked as *optimal* provide the best performance because no conversion step (i.e. number to low and high bits or base64 string to buffer) is required.
Examples
--------
@@ -296,7 +296,9 @@ function buildType(ref, type) {
jsType = "Object.<string," + jsType + ">";
else if (field.repeated)
jsType = "Array.<" + jsType + ">";
typeDef.push("@property {" + jsType + "} " + (field.optional ? "[" + field.name + "]" : field.name) + " " + (field.comment || type.name + " " + field.name + "."));
var name = util.safeProp(field.name);
name = name.substring(1, name.charAt(0) === "[" ? name.length - 1 : name.length);
typeDef.push("@property {" + jsType + "} " + (field.optional ? "[" + name + "]" : field.name) + " " + (field.comment || type.name + " " + field.name + "."));
});
push("");
pushComment(typeDef);
@@ -391,7 +393,7 @@ function buildType(ref, type) {
push("");
pushComment([
"Encodes the specified " + type.name + " message, length delimited. Does not implicitly {@link " + fullName + ".verify|verify} messages.",
"@param {" + fullName + "|Object.<string,*>} message " + type.name + " message or plain object to encode",
"@param {" + fullName + "$Properties} message " + type.name + " message or plain object to encode",
"@param {$protobuf.Writer} [writer] Writer to encode to",
"@returns {$protobuf.Writer} Writer"
]);
@@ -1,2 +1,4 @@
// experimental - debug library entry point.
"use strict";
module.exports = require("./src/index-debug");
module.exports = require("./src/index-debug");
@@ -1842,15 +1842,15 @@ export class Type extends NamespaceBase {
* @property {boolean} [objects=false] Sets empty objects for missing map fields even if `defaults=false`
* @property {boolean} [oneofs=false] Includes virtual oneof properties set to the present field's name, if any
*/
interface ConversionOptions {
type ConversionOptions = {
longs?: any;
enums?: any;
bytes?: any;
defaults?: boolean;
arrays?: boolean;
objects?: boolean;
oneofs?: boolean;
}
};
/**
* Common type constants.
@@ -2016,22 +2016,6 @@ export namespace types {
};
}
/**
* Any compatible Long instance.
*
* This is a minimal stand-alone definition of a Long instance. The actual type is that exported by long.js.
* @typedef Long
* @type {Object}
* @property {number} low Low bits
* @property {number} high High bits
* @property {boolean} unsigned Whether unsigned or not
*/
interface Long {
low: number;
high: number;
unsigned: boolean;
}
/**
* Various utility functions.
* @namespace
@@ -2870,10 +2854,10 @@ type FetchCallback = (error: Error, contents?: string) => void;
* @property {boolean} [binary=false] Whether expecting a binary response
* @property {boolean} [xhr=false] If `true`, forces the use of XMLHttpRequest
*/
interface FetchOptions {
type FetchOptions = {
binary?: boolean;
xhr?: boolean;
}
};
/**
* An allocator as used by {@link util.pool}.
@@ -1,2 +1,4 @@
// full library entry point.
"use strict";
module.exports = require("./src/index");
@@ -177,7 +177,7 @@ function isClassLike(element) {
// tests if an element is considered to be an interface
function isInterface(element) {
return element && (element.kind === "interface" || getTypeOf(element) === "Object" && element.properties && element.properties.length);
return element && element.kind === "interface";
}
// tests if an element is considered to be a namespace
@@ -296,7 +296,13 @@ function writeFunctionSignature(element, isConstructor, isTypeDef) {
// writes (a typedef as) an interface
function writeInterface(element) {
writeln("interface ", element.name, " {");
write("interface ", element.name);
writeInterfaceBody(element);
writeln();
}
function writeInterfaceBody(element) {
writeln("{");
++indent;
element.properties.forEach(function(property) {
write(property.name);
@@ -305,7 +311,7 @@ function writeInterface(element) {
writeln(": ", getTypeOf(property), ";");
});
--indent;
writeln("}");
write("}");
}
//
@@ -524,7 +530,9 @@ function handleTypeDef(element, parent) {
write("type ", element.name, " = ");
if (element.type && element.type.names.length === 1 && element.type.names[0] === "function")
writeFunctionSignature(element, false, true);
else
else if (getTypeOf(element) === "Object" && element.properties && element.properties.length) {
writeInterfaceBody(element);
} else
write(getTypeOf(element));
writeln(";");
}
@@ -1,2 +1,4 @@
// light library entry point.
"use strict";
module.exports = require("./src/index-light");
@@ -1,2 +1,4 @@
// minimal library entry point.
"use strict";
module.exports = require("./src/index-minimal");
module.exports = require("./src/index-minimal");
@@ -1,3 +1,4 @@
// deprecated - compatibility layer for v6.5 and earlier
// deprecated - compatibility layer for v6.5 and earlier (now named "minimal")
"use strict";
module.exports = require("./src/index-minimal");
module.exports = require("./src/index-minimal");
@@ -3,17 +3,6 @@ module.exports = LongBits;
var util = require("../util/minimal");
/**
* Any compatible Long instance.
*
* This is a minimal stand-alone definition of a Long instance. The actual type is that exported by long.js.
* @typedef Long
* @type {Object}
* @property {number} low Low bits
* @property {number} high High bits
* @property {boolean} unsigned Whether unsigned or not
*/
/**
* Constructs new long bits.
* @classdesc Helper class for working with the low and high bits of a 64 bit value.
@@ -70,6 +70,13 @@ util.isObject = function isObject(value) {
return value && typeof value === "object";
};
/*
* Any compatible Buffer instance.
* This is a minimal stand-alone definition of a Buffer instance. The actual type is that exported by node's typings.
* @typedef Buffer
* @type {Uint8Array}
*/
/**
* Node's Buffer class if available.
* @type {?function(new: Buffer)}
@@ -128,6 +135,16 @@ util.newBuffer = function newBuffer(sizeOrArray) {
*/
util.Array = typeof Uint8Array !== "undefined" ? Uint8Array /* istanbul ignore next */ : Array;
/*
* Any compatible Long instance.
* This is a minimal stand-alone definition of a Long instance. The actual type is that exported by long.js.
* @typedef Long
* @type {Object}
* @property {number} low Low bits
* @property {number} high High bits
* @property {boolean} unsigned Whether unsigned or not
*/
/**
* Long.js's Long class if available.
* @type {?function(new: Long)}
@@ -0,0 +1,9 @@
// minimal stub for Long instances for reference when not using long.js.
type Long = LongStub;
interface LongStub {
lo: number,
hi: number,
unsigned: boolean
}
@@ -0,0 +1,6 @@
// minimal stub for node types for reference when not using node.
type Buffer = BufferStub;
interface BufferStub extends Uint8Array {
}
@@ -1,3 +1,9 @@
// uncomment for browser only / non long.js versions
/*
/// <reference path="../stub-long.d.ts" />
/// <reference path="../stub-node.d.ts" />
*/
import * as protobuf from "..";
export const proto = {
@@ -30,9 +36,10 @@ protobuf.Class.create(root.lookupType("Hello"), Hello);
let hello = new Hello();
let buf = Hello.encode(hello.foo()).finish();
let writer = Hello.encode(hello.foo()) as protobuf.BufferWriter;
let buf = writer.finish();
let hello2 = Hello.decode(buf) as Hello;
process.stdout.write(JSON.stringify(hello2.foo().toObject(), null, 2));
// console.log(JSON.stringify(hello2.foo().toObject(), null, 2));
export const utf8 = protobuf.util.utf8;
@@ -70,7 +70,7 @@ $root.Test1 = (function() {
/**
* Encodes the specified Test1 message, length delimited. Does not implicitly {@link Test1.verify|verify} messages.
* @param {Test1|Object.<string,*>} message Test1 message or plain object to encode
* @param {Test1$Properties} message Test1 message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
@@ -258,7 +258,7 @@ $root.Test2 = (function() {
/**
* Encodes the specified Test2 message, length delimited. Does not implicitly {@link Test2.verify|verify} messages.
* @param {Test2|Object.<string,*>} message Test2 message or plain object to encode
* @param {Test2$Properties} message Test2 message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
@@ -373,9 +373,9 @@ $root.Test2 = (function() {
*/
$root.Test3 = (function() {
var valuesById = {}, values = Object.create(valuesById);
values["ONE"] = 1;
values["TWO"] = 2;
values["THREE"] = 3;
values[valuesById[1] = "ONE"] = 1;
values[valuesById[2] = "TWO"] = 2;
values[valuesById[3] = "THREE"] = 3;
return values;
})();
@@ -106,7 +106,7 @@ $root.Message = (function() {
/**
* Encodes the specified Message message, length delimited. Does not implicitly {@link Message.verify|verify} messages.
* @param {Message|Object.<string,*>} message Message message or plain object to encode
* @param {Message$Properties} message Message message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
@@ -479,8 +479,8 @@ $root.Message = (function() {
*/
Message.SomeEnum = (function() {
var valuesById = {}, values = Object.create(valuesById);
values["ONE"] = 1;
values["TWO"] = 2;
values[valuesById[1] = "ONE"] = 1;
values[valuesById[2] = "TWO"] = 2;
return values;
})();
@@ -69,7 +69,7 @@ $root.vector_tile = (function() {
/**
* Encodes the specified Tile message, length delimited. Does not implicitly {@link vector_tile.Tile.verify|verify} messages.
* @param {vector_tile.Tile|Object.<string,*>} message Tile message or plain object to encode
* @param {vector_tile.Tile$Properties} message Tile message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
@@ -218,10 +218,10 @@ $root.vector_tile = (function() {
*/
Tile.GeomType = (function() {
var valuesById = {}, values = Object.create(valuesById);
values["UNKNOWN"] = 0;
values["POINT"] = 1;
values["LINESTRING"] = 2;
values["POLYGON"] = 3;
values[valuesById[0] = "UNKNOWN"] = 0;
values[valuesById[1] = "POINT"] = 1;
values[valuesById[2] = "LINESTRING"] = 2;
values[valuesById[3] = "POLYGON"] = 3;
return values;
})();
@@ -298,7 +298,7 @@ $root.vector_tile = (function() {
/**
* Encodes the specified Value message, length delimited. Does not implicitly {@link vector_tile.Tile.Value.verify|verify} messages.
* @param {vector_tile.Tile.Value|Object.<string,*>} message Value message or plain object to encode
* @param {vector_tile.Tile.Value$Properties} message Value message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
@@ -599,7 +599,7 @@ $root.vector_tile = (function() {
/**
* Encodes the specified Feature message, length delimited. Does not implicitly {@link vector_tile.Tile.Feature.verify|verify} messages.
* @param {vector_tile.Tile.Feature|Object.<string,*>} message Feature message or plain object to encode
* @param {vector_tile.Tile.Feature$Properties} message Feature message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
@@ -904,7 +904,7 @@ $root.vector_tile = (function() {
/**
* Encodes the specified Layer message, length delimited. Does not implicitly {@link vector_tile.Tile.Layer.verify|verify} messages.
* @param {vector_tile.Tile.Layer|Object.<string,*>} message Layer message or plain object to encode
* @param {vector_tile.Tile.Layer$Properties} message Layer message or plain object to encode
* @param {$protobuf.Writer} [writer] Writer to encode to
* @returns {$protobuf.Writer} Writer
*/
Oops, something went wrong.

0 comments on commit c04d4a5

Please sign in to comment.