protobufjs-cli
Advanced tools
+7
-0
| # Changelog | ||
| ## [2.3.0](https://github.com/protobufjs/protobuf.js/compare/protobufjs-cli-v2.2.1...protobufjs-cli-v2.3.0) (2026-05-13) | ||
| ### Features | ||
| * Improve generated typings ([#2244](https://github.com/protobufjs/protobuf.js/issues/2244)) ([faa424e](https://github.com/protobufjs/protobuf.js/commit/faa424e3837fe43f1f010b0ccdeb583d808a57cf)) | ||
| ## [2.2.1](https://github.com/protobufjs/protobuf.js/compare/protobufjs-cli-v2.2.0...protobufjs-cli-v2.2.1) (2026-05-13) | ||
@@ -4,0 +11,0 @@ |
| { | ||
| "tags": { | ||
| "allowUnknownTags": false | ||
| "allowUnknownTags": true | ||
| }, | ||
@@ -5,0 +5,0 @@ "source": { |
| "use strict"; | ||
| var typeParserPatched = false; | ||
| function normalizeType(type) { | ||
| return type.replace(/\r?\n|\r/g, "\n"); | ||
| } | ||
| function patchTypeScriptTypes(dictionary) { | ||
| var type = require("jsdoc/tag/type"); | ||
| var parse = type.parse, | ||
| typeTag = dictionary.lookUp("type"); | ||
| if (typeTag && !typeTag.protobufjsPatched) { | ||
| typeTag.onTagText = function onTypeTagText(text) { | ||
| var openIdx = text.indexOf("{"), | ||
| closeIdx = text.indexOf("}"); | ||
| if (openIdx !== 0 || closeIdx <= openIdx + 1) | ||
| text = "{" + text + "}"; | ||
| return text; | ||
| }; | ||
| typeTag.protobufjsPatched = true; | ||
| } | ||
| if (typeParserPatched) | ||
| return; | ||
| typeParserPatched = true; | ||
| type.parse = function parseTypeScriptType(tagValue, canHaveName, canHaveType) { | ||
| try { | ||
| return parse(tagValue, canHaveName, canHaveType); | ||
| } catch (e) { | ||
| if (!canHaveType) | ||
| throw e; | ||
| var text = String(tagValue || ""); | ||
| var open = text.indexOf("{"); | ||
| if (open < 0) | ||
| throw e; | ||
| var depth = 0; | ||
| var close = -1; | ||
| for (var i = open; i < text.length; ++i) { | ||
| var ch = text.charAt(i); | ||
| if (ch === "{") | ||
| ++depth; | ||
| else if (ch === "}" && --depth === 0) { | ||
| close = i; | ||
| break; | ||
| } | ||
| } | ||
| if (close < 0) | ||
| throw e; | ||
| var expression = normalizeType(text.substring(open + 1, close)).trim(); | ||
| if (!/[&;]|\?:|=>|\bkeyof\b|\btypeof\b|^\s*\{/.test(expression)) | ||
| throw e; | ||
| var name = canHaveName ? text.substring(close + 1).trim() : ""; | ||
| return { | ||
| type: [ expression ], | ||
| typeExpression: expression, | ||
| name: name | ||
| }; | ||
| } | ||
| }; | ||
| } | ||
| exports.defineTags = function(dictionary) { | ||
| patchTypeScriptTypes(dictionary); | ||
@@ -18,5 +88,5 @@ dictionary.defineTag("template", { | ||
| onTagged: function(doclet, tag) { | ||
| doclet.tsType = tag.text; | ||
| doclet.tsType = normalizeType(tag.text); | ||
| } | ||
| }); | ||
| }; |
+162
-42
@@ -23,5 +23,2 @@ "use strict"; | ||
| // queued interfaces | ||
| var queuedInterfaces = []; | ||
| // whether writing the first line | ||
@@ -86,10 +83,2 @@ var firstLine = true; | ||
| // process queued | ||
| while (queuedInterfaces.length) { | ||
| var element = queuedInterfaces.shift(); | ||
| begin(element); | ||
| writeInterface(element); | ||
| writeln(";"); | ||
| } | ||
| // end wrap | ||
@@ -109,3 +98,2 @@ if (options.module) { | ||
| seen = options = {}; | ||
| queuedInterfaces = []; | ||
| } | ||
@@ -214,2 +202,4 @@ }; | ||
| }); | ||
| } else if (tag.name === "deprecated") { | ||
| writeln(" * @deprecated"); | ||
| } | ||
@@ -281,5 +271,2 @@ }); | ||
| // Ensure upper case Object for map expressions below | ||
| name = name.replace(/\bobject\b/g, "Object"); | ||
| // Convert innermost generic types first so Array.<Object.<...>> | ||
@@ -309,5 +296,5 @@ // and Object.<string,Array.<...>> are both handled correctly | ||
| // Convert plain Object back to just object | ||
| name = name.replace(/\b(Object\b(?!\.))/g, function($0, $1) { | ||
| return $1.toLowerCase(); | ||
| // Convert plain Object back to just object, but preserve qualified names like foo.Object | ||
| name = name.replace(/(^|[^\w$.])Object\b(?![.<])/g, function($0, prefix) { | ||
| return prefix + "object"; | ||
| }); | ||
@@ -318,2 +305,95 @@ | ||
| function splitTypeList(text, delimiter) { | ||
| var parts = []; | ||
| var start = 0; | ||
| var depth = { | ||
| brace: 0, | ||
| bracket: 0, | ||
| paren: 0, | ||
| angle: 0 | ||
| }; | ||
| var quote = null; | ||
| for (var i = 0; i < text.length; ++i) { | ||
| var ch = text.charAt(i); | ||
| if (quote) { | ||
| if (ch === "\\") | ||
| ++i; | ||
| else if (ch === quote) | ||
| quote = null; | ||
| continue; | ||
| } | ||
| if (ch === "\"" || ch === "'") { | ||
| quote = ch; | ||
| continue; | ||
| } | ||
| switch (ch) { | ||
| case "{": ++depth.brace; break; | ||
| case "}": --depth.brace; break; | ||
| case "[": ++depth.bracket; break; | ||
| case "]": --depth.bracket; break; | ||
| case "(": ++depth.paren; break; | ||
| case ")": --depth.paren; break; | ||
| case "<": ++depth.angle; break; | ||
| case ">": | ||
| if (depth.angle > 0) | ||
| --depth.angle; | ||
| break; | ||
| default: | ||
| if (ch === delimiter && !depth.brace && !depth.bracket && !depth.paren && !depth.angle) { | ||
| parts.push(text.substring(start, i).trim()); | ||
| start = i + 1; | ||
| } | ||
| break; | ||
| } | ||
| } | ||
| parts.push(text.substring(start).trim()); | ||
| return parts.filter(function(part) { | ||
| return part.length; | ||
| }); | ||
| } | ||
| function getCallSignatures(type) { | ||
| type = type && type.trim(); | ||
| if (!type || type.charAt(0) !== "{" || type.charAt(type.length - 1) !== "}") | ||
| return null; | ||
| var body = type.substring(1, type.length - 1).trim(); | ||
| if (body.charAt(0) !== "(") | ||
| return null; | ||
| var signatures = splitTypeList(body, ";"); | ||
| if (!signatures.every(function(signature) { | ||
| return getCallSignatureParametersEnd(signature) > 0; | ||
| })) | ||
| return null; | ||
| return signatures.map(function(signature) { | ||
| return /;\s*$/.test(signature) ? signature : signature + ";"; | ||
| }); | ||
| } | ||
| function getCallSignatureParametersEnd(signature) { | ||
| var depth = 0; | ||
| var quote = null; | ||
| for (var i = 0; i < signature.length; ++i) { | ||
| var ch = signature.charAt(i); | ||
| if (quote) { | ||
| if (ch === "\\") | ||
| ++i; | ||
| else if (ch === quote) | ||
| quote = null; | ||
| continue; | ||
| } | ||
| if (ch === "\"" || ch === "'") { | ||
| quote = ch; | ||
| continue; | ||
| } | ||
| if (ch === "(") | ||
| ++depth; | ||
| else if (ch === ")" && --depth === 0) { | ||
| while (++i < signature.length && /\s/.test(signature.charAt(i))) | ||
| continue; | ||
| return signature.charAt(i) === ":" ? i : -1; | ||
| } | ||
| } | ||
| return -1; | ||
| } | ||
| // begins writing the definition of the specified element | ||
@@ -389,3 +469,5 @@ function begin(element, is_interface) { | ||
| var typeName; | ||
| if (element.returns && element.returns.length && (typeName = getTypeOf(element.returns[0])) !== "undefined") | ||
| if (element.tsType) | ||
| write(element.tsType.replace(/\r?\n|\r/g, "\n")); | ||
| else if (element.returns && element.returns.length && (typeName = getTypeOf(element.returns[0])) !== "undefined") | ||
| write(typeName); | ||
@@ -399,3 +481,3 @@ else | ||
| function writeInterface(element) { | ||
| write("interface ", element.name); | ||
| write("interface ", element.name, " "); | ||
| writeInterfaceBody(element); | ||
@@ -418,5 +500,3 @@ writeln(); | ||
| writeComment(property.description); | ||
| if (inClass) | ||
| write("public "); | ||
| else if (declare) | ||
| if (declare && !inClass) | ||
| write("let "); | ||
@@ -632,2 +712,3 @@ write(property.name); | ||
| element.properties.forEach(function(property, i) { | ||
| writeComment(property.description); | ||
| write(property.name); | ||
@@ -662,3 +743,4 @@ if (property.defaultvalue !== undefined) | ||
| if (inClass) { | ||
| write(element.access || "public", " "); | ||
| if (element.access && element.access !== "public") | ||
| write(element.access, " "); | ||
| if (element.scope === "static") | ||
@@ -688,2 +770,20 @@ write("static "); | ||
| function writeFunctionName(element, insideClass, exported) { | ||
| if (insideClass) { | ||
| if (element.access && element.access !== "public") | ||
| write(element.access, " "); | ||
| if (element.scope === "static") | ||
| write("static "); | ||
| else if (element.virtual) | ||
| write("abstract "); | ||
| } else { | ||
| if (exported) | ||
| write("export "); | ||
| write("function "); | ||
| } | ||
| write(element.name); | ||
| if (element.templates && element.templates.length) | ||
| write("<", element.templates.join(", "), ">"); | ||
| } | ||
| // handles a function or method | ||
@@ -698,12 +798,18 @@ function handleFunction(element, parent, isConstructor) { | ||
| insideClass = isClassLike(parent); | ||
| if (insideClass) { | ||
| write(element.access || "public", " "); | ||
| if (element.scope === "static") | ||
| write("static "); | ||
| } else | ||
| write("function "); | ||
| write(element.name); | ||
| if (element.templates && element.templates.length) | ||
| write("<", element.templates.join(", "), ">"); | ||
| writeFunctionName(element, insideClass); | ||
| } | ||
| var signatures = null; | ||
| if (element.type && element.type.names && element.type.names.length === 1) | ||
| signatures = getCallSignatures(element.type.names[0]); | ||
| if (signatures) { | ||
| writeln(signatures[0]); | ||
| var exported = !insideClass && (element.scope === "global" || element.isEnum && element.scope === undefined) && !options.module; | ||
| for (var i = 1; i < signatures.length; ++i) { | ||
| writeFunctionName(element, insideClass, exported); | ||
| writeln(signatures[i]); | ||
| } | ||
| if (!insideClass) | ||
| handleNamespace(element); | ||
| return; | ||
| } | ||
| writeFunctionSignature(element, isConstructor, false); | ||
@@ -717,11 +823,26 @@ writeln(";"); | ||
| function handleTypeDef(element, parent) { | ||
| if (isInterface(element)) { | ||
| if (isClassLike(parent)) | ||
| queuedInterfaces.push(element); | ||
| else { | ||
| begin(element); | ||
| writeInterface(element); | ||
| } | ||
| var suffix = "." + element.name; | ||
| var owner = element.longname && element.longname !== element.name && element.longname.lastIndexOf(suffix) === element.longname.length - suffix.length | ||
| ? element.longname.substring(0, element.longname.length - suffix.length) | ||
| : null; | ||
| // Emit nested typedefs like Foo.Bar as declarations in namespace Foo | ||
| if (owner && (!parent || parent.longname !== owner)) { | ||
| if (element.scope === "global" && !options.module) | ||
| write("export "); | ||
| writeln("namespace ", owner, " {"); | ||
| ++indent; | ||
| handleTypeDef(element, { longname: owner }); | ||
| --indent; | ||
| writeln("}"); | ||
| return; | ||
| } | ||
| // Emit object typedefs with properties as interfaces, any others as type aliases | ||
| var type = getTypeOf(element); | ||
| if (isInterface(element) || type === "object" && element.properties && element.properties.length) { | ||
| begin(element); | ||
| writeInterface(element); | ||
| } else { | ||
| writeComment(element.comment, true); | ||
| begin(element); | ||
| write("type ", element.name); | ||
@@ -734,3 +855,2 @@ if (element.templates && element.templates.length) | ||
| else { | ||
| var type = getTypeOf(element); | ||
| if (element.type && element.type.names.length === 1 && element.type.names[0] === "function") | ||
@@ -737,0 +857,0 @@ writeFunctionSignature(element, false, true); |
+1
-1
| { | ||
| "name": "protobufjs-cli", | ||
| "description": "Translates between file formats and generates static code as well as TypeScript definitions.", | ||
| "version": "2.2.1", | ||
| "version": "2.3.0", | ||
| "author": "Daniel Wirtz <dcode+protobufjs@dcode.io>", | ||
@@ -6,0 +6,0 @@ "repository": { |
+2
-2
@@ -13,3 +13,3 @@ type pbtsCallback = (err: Error|null, output?: string) => void; | ||
| * Generates TypeScript definitions from a JavaScript source. | ||
| * @param {string|Buffer} source JavaScript source | ||
| * @param {string|Uint8Array} source JavaScript source | ||
| * @param {string[]} args Command line arguments | ||
@@ -19,2 +19,2 @@ * @param {function(?Error, string=)} [callback] Optional completion callback | ||
| */ | ||
| export function process(source: string|Buffer, args: string[], callback?: pbtsCallback): number|undefined; | ||
| export function process(source: string|Uint8Array, args: string[], callback?: pbtsCallback): number|undefined; |
+31
-10
@@ -26,3 +26,3 @@ "use strict"; | ||
| * Generates TypeScript definitions from a JavaScript source. | ||
| * @param {string|Buffer} source JavaScript source | ||
| * @param {string|Uint8Array} source JavaScript source | ||
| * @param {string[]} args Command line arguments | ||
@@ -82,3 +82,3 @@ * @param {function(?Error, string=)} [callback] Optional completion callback | ||
| "", | ||
| " -i, --import Comma delimited list of imports. Local names will equal camelCase of the basename.", | ||
| " -i, --import Comma delimited list of imports, optionally as localName=path.", | ||
| "", | ||
@@ -93,3 +93,3 @@ " --no-constructor Emits private constructors for reflection-backed declarations.", | ||
| "", | ||
| " -m, --main Whether building the main library without any imports.", | ||
| " -m, --main Whether building a standalone file without any imports.", | ||
| "", | ||
@@ -197,2 +197,16 @@ "usage: " + chalk.bold.green("pbts") + " [options] file1.js file2.js ..." + chalk.bold.gray(" (or) ") + "other | " + chalk.bold.green("pbts") + " [options] -", | ||
| function addImport(imports, importItem) { | ||
| var equals = importItem.indexOf("="); | ||
| if (equals < 0) { | ||
| imports[getImportName(importItem)] = importItem; | ||
| return; | ||
| } | ||
| var importName = importItem.substring(0, equals), | ||
| importPath = importItem.substring(equals + 1); | ||
| if (importName[0] === "\\" && importName[1] === "$") | ||
| importName = importName.substring(1); | ||
| imports[importName] = importPath; | ||
| } | ||
| function finish() { | ||
@@ -202,3 +216,3 @@ var output = []; | ||
| output.push( | ||
| "// DO NOT EDIT! This is a generated file. Edit the JSDoc in src/*.js instead and run 'npm run build:types'.", | ||
| "// DO NOT EDIT! This is a generated file. Edit the source file instead and regenerate.", | ||
| "" | ||
@@ -212,12 +226,15 @@ ); | ||
| if (!argv.main) { | ||
| if (!argv.main || argv.import) { | ||
| // Ensure we have a usable array of imports | ||
| var importArray = typeof argv.import === "string" ? argv.import.split(",") : argv.import || []; | ||
| var importArray = []; | ||
| [].concat(argv.import || []).forEach(function(importItem) { | ||
| importArray = importArray.concat(importItem.split(",")); | ||
| }); | ||
| // Build an object of imports and paths | ||
| var imports = { | ||
| var imports = argv.main ? {} : { | ||
| $protobuf: "protobufjs" | ||
| }; | ||
| importArray.forEach(function(importItem) { | ||
| imports[getImportName(importItem)] = importItem; | ||
| addImport(imports, importItem); | ||
| }); | ||
@@ -230,6 +247,10 @@ | ||
| output.push("import Long = require(\"long\");"); | ||
| if (!argv.main) | ||
| output.push("import Long = require(\"long\");"); | ||
| output.push(""); | ||
| } | ||
| output = output.join("\n") + "\n" + out.join(""); | ||
| output = output.length | ||
| ? output.join("\n") + "\n" + out.join("") | ||
| : out.join(""); | ||
@@ -236,0 +257,0 @@ try { |
+2
-2
@@ -101,3 +101,3 @@ # protobufjs-cli | ||
| -i, --import Comma delimited list of imports. Local names will equal camelCase of the basename. | ||
| -i, --import Comma delimited list of imports, optionally as localName=path. | ||
@@ -112,3 +112,3 @@ --no-constructor Emits private constructors for reflection-backed declarations. | ||
| -m, --main Whether building the main library without any imports. | ||
| -m, --main Whether building a standalone file without any imports. | ||
@@ -115,0 +115,0 @@ usage: pbts [options] file1.js file2.js ... (or) other | pbts [options] - |
+157
-44
@@ -39,3 +39,3 @@ "use strict"; | ||
| if (root.comment) { | ||
| pushComment("@fileoverview " + root.comment); | ||
| pushComment([ "@fileoverview " + root.comment ]); | ||
| push(""); | ||
@@ -110,3 +110,3 @@ } | ||
| function aOrAn(name) { | ||
| return ((/^[hH](?:ou|on|ei)/.test(name) || /^[aeiouAEIOU][a-z]/.test(name)) && !/^us/i.test(name) | ||
| return ((/^[hH](?:ou|on|ei)/.test(name) || /^[aeiouAEIOU][a-z]/.test(name)) && !/^(?:use?|uni([^nmd]|mo)|one|once)/i.test(name) | ||
| ? "an " | ||
@@ -354,3 +354,3 @@ : "a ") + name; | ||
| function toJsType(field, parentIsInterface = false) { | ||
| function toJsType(field, parentIsInterface = false, withNarrowing = false) { | ||
| var type; | ||
@@ -392,3 +392,10 @@ | ||
| if (field.resolve().resolvedType) { | ||
| type = exportName(field.resolvedType, asInterface); | ||
| if (field.resolvedType instanceof protobuf.Type) | ||
| type = withNarrowing | ||
| ? shapeName(field.resolvedType) | ||
| : asInterface | ||
| ? propertiesName(field.resolvedType) | ||
| : exportName(field.resolvedType, asInterface); | ||
| else | ||
| type = exportName(field.resolvedType, asInterface); | ||
| } | ||
@@ -430,2 +437,13 @@ else { | ||
| function toTypePropName(name, optional) { | ||
| var prop = util.safeProp(name); // either .name or ["name"] | ||
| if (prop.charAt(0) === ".") | ||
| prop = prop.substring(1); | ||
| else | ||
| prop = JSON.parse(prop.substring(1, prop.length - 1)); | ||
| if (!/^[$\w]+$/.test(prop) || util.patterns.reservedRe.test(prop)) | ||
| prop = JSON.stringify(prop); | ||
| return prop + (optional ? "?" : ""); | ||
| } | ||
| function isNullable(field) { | ||
@@ -435,3 +453,99 @@ return field.hasPresence && !field.required; | ||
| function propertiesName(type) { | ||
| return exportName(type) + ".$Properties"; | ||
| } | ||
| function shapeName(type) { | ||
| return exportName(type) + ".$Shape"; | ||
| } | ||
| function narrowedType(type) { | ||
| return exportName(type) + " & " + shapeName(type); | ||
| } | ||
| function oneofType(oneof, selectedField) { | ||
| var props = [ toTypePropName(oneof.name, true) + ": " + (selectedField ? JSON.stringify(selectedField.name) : "undefined") ]; | ||
| oneof.oneof.forEach(function(fieldName) { | ||
| var field = oneof.parent.fields[fieldName]; | ||
| props.push(toTypePropName(field.name, field !== selectedField) + ": " + (field === selectedField ? toJsType(field, true, true) : "null")); | ||
| }); | ||
| return "{ " + props.join("; ") + " }"; | ||
| } | ||
| function oneofTypes(type) { | ||
| return type.oneofsArray.filter(function(oneof) { | ||
| return !oneof.isProto3Optional; | ||
| }).map(function(oneof) { | ||
| oneof.resolve(); | ||
| var cases = [ oneofType(oneof) ]; | ||
| oneof.oneof.forEach(function(fieldName) { | ||
| cases.push(oneofType(oneof, oneof.parent.fields[fieldName])); | ||
| }); | ||
| return "(" + cases.join("|") + ")"; | ||
| }); | ||
| } | ||
| function hasNarrowing(type, seen) { | ||
| if (!seen) | ||
| seen = {}; | ||
| if (seen[type.fullName]) | ||
| return false; | ||
| seen[type.fullName] = true; | ||
| if (type.oneofsArray.some(function(oneof) { return !oneof.isProto3Optional; })) { | ||
| delete seen[type.fullName]; | ||
| return true; | ||
| } | ||
| var narrowed = type.fieldsArray.some(function(field) { | ||
| field.resolve(); | ||
| return field.resolvedType instanceof protobuf.Type && hasNarrowing(field.resolvedType, seen); | ||
| }); | ||
| delete seen[type.fullName]; | ||
| return narrowed; | ||
| } | ||
| function returnTags(typeName, description, tsType) { | ||
| return [ "@returns {" + (tsType || typeName) + "} " + description ]; | ||
| } | ||
| function propertyType(field, withNarrowing) { | ||
| var jsType = toJsType(field, /* parentIsInterface = */ true, withNarrowing); | ||
| var nullable = false; | ||
| if (config["null-semantics"]) { | ||
| // With semantic nulls, only explicit optional fields and one-of members can be set to null | ||
| // Implicit fields (proto3), maps and lists can be omitted, but if specified must be non-null | ||
| // Implicit fields will take their default value when the message is constructed | ||
| if (field.optional) { | ||
| if (isNullable(field)) | ||
| jsType = jsType + "|null"; | ||
| nullable = true; | ||
| } | ||
| } | ||
| else { | ||
| // Without semantic nulls, everything is optional in proto3 | ||
| // Do not allow |undefined to keep backwards compatibility | ||
| if (field.optional) { | ||
| jsType = jsType + "|null"; | ||
| nullable = true; | ||
| } | ||
| } | ||
| return { | ||
| jsType: jsType, | ||
| nullable: nullable | ||
| }; | ||
| } | ||
| function shapeType(type, oneofs) { | ||
| if (!hasNarrowing(type)) | ||
| return propertiesName(type); | ||
| var props = []; | ||
| type.fieldsArray.forEach(function(field) { | ||
| var prop = propertyType(field, /* withNarrowing = */ true); | ||
| props.push(" " + toTypePropName(field.name, prop.nullable) + ": " + prop.jsType + ";"); | ||
| }); | ||
| props.push(" " + toTypePropName("$unknowns", true) + ": Array.<Uint8Array>;"); | ||
| return "{\n" + props.join("\n") + "\n}" + (oneofs.length ? " & (\n " + oneofs.join("\n) & (\n ") + "\n)" : ""); | ||
| } | ||
| function buildType(ref, type) { | ||
| var oneofs = oneofTypes(type); | ||
@@ -441,36 +555,31 @@ if (config.comments) { | ||
| "Properties of " + aOrAn(type.name) + ".", | ||
| type.parent instanceof protobuf.Root ? "@exports " + escapeName("I" + type.name) : "@memberof " + exportName(type.parent), | ||
| "@interface " + escapeName("I" + type.name) | ||
| "@typedef {Object} " + propertiesName(type) | ||
| ]; | ||
| type.fieldsArray.forEach(function(field) { | ||
| var jsType = toJsType(field, /* parentIsInterface = */ true); | ||
| var nullable = false; | ||
| if (config["null-semantics"]) { | ||
| // With semantic nulls, only explicit optional fields and one-of members can be set to null | ||
| // Implicit fields (proto3), maps and lists can be omitted, but if specified must be non-null | ||
| // Implicit fields will take their default value when the message is constructed | ||
| if (field.optional) { | ||
| if (isNullable(field)) { | ||
| jsType = jsType + "|null|undefined"; | ||
| nullable = true; | ||
| } | ||
| else { | ||
| jsType = jsType + "|undefined"; | ||
| nullable = true; | ||
| } | ||
| } | ||
| } | ||
| else { | ||
| // Without semantic nulls, everything is optional in proto3 | ||
| // Do not allow |undefined to keep backwards compatibility | ||
| if (field.optional) { | ||
| jsType = jsType + "|null"; | ||
| nullable = true; | ||
| } | ||
| } | ||
| typeDef.push("@property {" + jsType + "} " + toPropName(field, nullable) + " " + (field.comment || type.name + " " + field.name)); | ||
| var prop = propertyType(field, /* withNarrowing = */ false); | ||
| typeDef.push("@property {" + prop.jsType + "} " + toPropName(field, prop.nullable) + " " + (field.comment || type.name + " " + field.name)); | ||
| }); | ||
| if (oneofs.length) { | ||
| type.oneofsArray.forEach(function(oneof) { | ||
| if (oneof.isProto3Optional) | ||
| return; | ||
| typeDef.push("@property {" + oneof.oneof.map(JSON.stringify).join("|") + "} [" + oneof.name + "] " + (oneof.comment || type.name + " " + oneof.name)); | ||
| }); | ||
| } | ||
| typeDef.push("@property {Array.<Uint8Array>} [$unknowns] Unknown fields preserved while decoding"); | ||
| push(""); | ||
| pushComment(typeDef); | ||
| push(""); | ||
| pushComment([ | ||
| "Properties of " + aOrAn(type.name) + ".", | ||
| type.parent instanceof protobuf.Root ? "@exports " + escapeName("I" + type.name) : "@memberof " + exportName(type.parent), | ||
| "@interface " + escapeName("I" + type.name), | ||
| "@augments " + propertiesName(type), | ||
| "@deprecated Use " + propertiesName(type) + " instead." | ||
| ]); | ||
| push(""); | ||
| pushComment([ | ||
| (oneofs.length ? "Narrowed shape" : "Shape") + " of " + aOrAn(type.name) + ".", | ||
| "@typedef {" + shapeType(type, oneofs) + "} " + shapeName(type) | ||
| ]); | ||
| } | ||
@@ -484,5 +593,4 @@ | ||
| "@classdesc " + (type.comment || "Represents " + aOrAn(type.name) + "."), | ||
| config.comments ? "@implements " + escapeName("I" + type.name) : null, | ||
| "@constructor", | ||
| "@param {" + exportName(type, true) + "=} [" + (config.beautify ? "properties" : "p") + "] Properties to set" | ||
| "@param {" + propertiesName(type) + "=} [" + (config.beautify ? "properties" : "p") + "] Properties to set" | ||
| ]; | ||
@@ -582,5 +690,10 @@ if (config.comments) { | ||
| "@static", | ||
| "@param {" + exportName(type, true) + "=} [properties] Properties to set", | ||
| "@param {" + propertiesName(type) + "=} [properties] Properties to set", | ||
| "@returns {" + exportName(type) + "} " + type.name + " instance" | ||
| ]); | ||
| ].concat([ | ||
| "@type {{\n" + | ||
| " (properties: " + shapeName(type) + "): " + narrowedType(type) + ";\n" + | ||
| " (properties?: " + propertiesName(type) + "): " + exportName(type) + ";\n" + | ||
| "}}" | ||
| ])); | ||
| push(escapeName(type.name) + ".create = function create(properties) {"); | ||
@@ -600,3 +713,3 @@ ++indent; | ||
| "@static", | ||
| "@param {" + exportName(type, !config.forceMessage) + "} " + (config.beautify ? "message" : "m") + " " + type.name + " message or plain object to encode", | ||
| "@param {" + (config.forceMessage ? exportName(type) : propertiesName(type)) + "} " + (config.beautify ? "message" : "m") + " " + type.name + " message or plain object to encode", | ||
| "@param {$protobuf.Writer} [" + (config.beautify ? "writer" : "w") + "] Writer to encode to", | ||
@@ -614,3 +727,3 @@ "@returns {$protobuf.Writer} Writer" | ||
| "@static", | ||
| "@param {" + exportName(type, !config.forceMessage) + "} message " + type.name + " message or plain object to encode", | ||
| "@param {" + (config.forceMessage ? exportName(type) : propertiesName(type)) + "} message " + type.name + " message or plain object to encode", | ||
| "@param {$protobuf.Writer} [writer] Writer to encode to", | ||
@@ -635,7 +748,7 @@ "@returns {$protobuf.Writer} Writer" | ||
| "@param {$protobuf.Reader|Uint8Array} " + (config.beautify ? "reader" : "r") + " Reader or buffer to decode from", | ||
| "@param {number} [" + (config.beautify ? "length" : "l") + "] Message length if known beforehand", | ||
| "@returns {" + exportName(type) + "} " + type.name, | ||
| "@param {number} [" + (config.beautify ? "length" : "l") + "] Message length if known beforehand" | ||
| ].concat(returnTags(exportName(type), type.name, narrowedType(type))).concat([ | ||
| "@throws {Error} If the payload is not a reader or valid buffer", | ||
| "@throws {$protobuf.util.ProtocolError} If required fields are missing" | ||
| ]); | ||
| ])); | ||
| buildFunction(type, "decode", protobuf.decoder(type)); | ||
@@ -650,7 +763,7 @@ | ||
| "@static", | ||
| "@param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from", | ||
| "@returns {" + exportName(type) + "} " + type.name, | ||
| "@param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from" | ||
| ].concat(returnTags(exportName(type), type.name, narrowedType(type))).concat([ | ||
| "@throws {Error} If the payload is not a reader or valid buffer", | ||
| "@throws {$protobuf.util.ProtocolError} If required fields are missing" | ||
| ]); | ||
| ])); | ||
| push(escapeName(type.name) + ".decodeDelimited = function decodeDelimited(reader) {"); | ||
@@ -657,0 +770,0 @@ ++indent; |
153391
8.06%3407
9.51%