diff --git a/packages/protons-runtime/src/codecs/codec.ts b/packages/protons-runtime/src/codec.ts similarity index 78% rename from packages/protons-runtime/src/codecs/codec.ts rename to packages/protons-runtime/src/codec.ts index 7332fd7..ab9a050 100644 --- a/packages/protons-runtime/src/codecs/codec.ts +++ b/packages/protons-runtime/src/codec.ts @@ -24,13 +24,13 @@ export interface EncodingLengthFunction { export interface Codec { name: string - type: number + type: CODEC_TYPES encode: EncodeFunction decode: DecodeFunction encodingLength: EncodingLengthFunction } -export function createCodec (name: string, type: number, encode: EncodeFunction, decode: DecodeFunction, encodingLength: EncodingLengthFunction): Codec { +export function createCodec (name: string, type: CODEC_TYPES, encode: EncodeFunction, decode: DecodeFunction, encodingLength: EncodingLengthFunction): Codec { return { name, type, diff --git a/packages/protons-runtime/src/codecs/bool.ts b/packages/protons-runtime/src/codecs/bool.ts index aa3c0d1..ec9932b 100644 --- a/packages/protons-runtime/src/codecs/bool.ts +++ b/packages/protons-runtime/src/codecs/bool.ts @@ -1,4 +1,5 @@ -import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js' +import { createCodec, CODEC_TYPES } from '../codec.js' +import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js' const encodingLength: EncodingLengthFunction = function boolEncodingLength () { return 1 diff --git a/packages/protons-runtime/src/codecs/bytes.ts b/packages/protons-runtime/src/codecs/bytes.ts index 37123f2..b8e826e 100644 --- a/packages/protons-runtime/src/codecs/bytes.ts +++ b/packages/protons-runtime/src/codecs/bytes.ts @@ -1,7 +1,8 @@ import { Uint8ArrayList } from 'uint8arraylist' import { unsigned } from '../utils/varint.js' -import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js' +import { createCodec, CODEC_TYPES } from '../codec.js' +import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js' const encodingLength: EncodingLengthFunction = function bytesEncodingLength (val) { const len = val.byteLength diff --git a/packages/protons-runtime/src/codecs/double.ts b/packages/protons-runtime/src/codecs/double.ts index 1d887fc..9aabc63 100644 --- a/packages/protons-runtime/src/codecs/double.ts +++ b/packages/protons-runtime/src/codecs/double.ts @@ -1,5 +1,6 @@ import { Uint8ArrayList } from 'uint8arraylist' -import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js' +import { createCodec, CODEC_TYPES } from '../codec.js' +import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js' const encodingLength: EncodingLengthFunction = function doubleEncodingLength () { return 8 diff --git a/packages/protons-runtime/src/codecs/enum.ts b/packages/protons-runtime/src/codecs/enum.ts index 26f8578..f7d5f9a 100644 --- a/packages/protons-runtime/src/codecs/enum.ts +++ b/packages/protons-runtime/src/codecs/enum.ts @@ -1,6 +1,7 @@ import { unsigned } from '../utils/varint.js' -import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, Codec, CODEC_TYPES } from './codec.js' +import { createCodec, CODEC_TYPES } from '../codec.js' +import type { DecodeFunction, EncodeFunction, EncodingLengthFunction, Codec } from '../codec.js' export function enumeration (e: T): Codec { const encodingLength: EncodingLengthFunction = function enumEncodingLength (val: string) { diff --git a/packages/protons-runtime/src/codecs/fixed32.ts b/packages/protons-runtime/src/codecs/fixed32.ts index cd29e3d..727e547 100644 --- a/packages/protons-runtime/src/codecs/fixed32.ts +++ b/packages/protons-runtime/src/codecs/fixed32.ts @@ -1,5 +1,6 @@ import { Uint8ArrayList } from 'uint8arraylist' -import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js' +import { createCodec, CODEC_TYPES } from '../codec.js' +import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js' const encodingLength: EncodingLengthFunction = function fixed32EncodingLength () { return 4 diff --git a/packages/protons-runtime/src/codecs/fixed64.ts b/packages/protons-runtime/src/codecs/fixed64.ts index d8113f1..cc3bc78 100644 --- a/packages/protons-runtime/src/codecs/fixed64.ts +++ b/packages/protons-runtime/src/codecs/fixed64.ts @@ -1,5 +1,6 @@ import { Uint8ArrayList } from 'uint8arraylist' -import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js' +import { createCodec, CODEC_TYPES } from '../codec.js' +import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js' const encodingLength: EncodingLengthFunction = function int64EncodingLength (val) { return 8 diff --git a/packages/protons-runtime/src/codecs/float.ts b/packages/protons-runtime/src/codecs/float.ts index 10270af..7ccdda2 100644 --- a/packages/protons-runtime/src/codecs/float.ts +++ b/packages/protons-runtime/src/codecs/float.ts @@ -1,5 +1,6 @@ import { Uint8ArrayList } from 'uint8arraylist' -import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js' +import { createCodec, CODEC_TYPES } from '../codec.js' +import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js' const encodingLength: EncodingLengthFunction = function floatEncodingLength () { return 4 diff --git a/packages/protons-runtime/src/codecs/int32.ts b/packages/protons-runtime/src/codecs/int32.ts index 0889d58..ef4c636 100644 --- a/packages/protons-runtime/src/codecs/int32.ts +++ b/packages/protons-runtime/src/codecs/int32.ts @@ -1,5 +1,6 @@ import { signed } from '../utils/varint.js' -import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js' +import { createCodec, CODEC_TYPES } from '../codec.js' +import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js' const encodingLength: EncodingLengthFunction = function int32EncodingLength (val) { return signed.encodingLength(val) diff --git a/packages/protons-runtime/src/codecs/int64.ts b/packages/protons-runtime/src/codecs/int64.ts index d58c0a7..47f571f 100644 --- a/packages/protons-runtime/src/codecs/int64.ts +++ b/packages/protons-runtime/src/codecs/int64.ts @@ -1,5 +1,6 @@ import { signed } from '../utils/big-varint.js' -import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js' +import { createCodec, CODEC_TYPES } from '../codec.js' +import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js' const encodingLength: EncodingLengthFunction = function int64EncodingLength (val) { return signed.encodingLength(val) diff --git a/packages/protons-runtime/src/codecs/message.ts b/packages/protons-runtime/src/codecs/message.ts index 009e14d..602a091 100644 --- a/packages/protons-runtime/src/codecs/message.ts +++ b/packages/protons-runtime/src/codecs/message.ts @@ -1,7 +1,8 @@ import { unsigned } from '../utils/varint.js' -import type { FieldDef, FieldDefs } from '../index.js' -import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, Codec, CODEC_TYPES } from './codec.js' +import { createCodec, CODEC_TYPES } from '../codec.js' +import type { DecodeFunction, EncodeFunction, EncodingLengthFunction, Codec } from '../codec.js' import { Uint8ArrayList } from 'uint8arraylist' +import type { FieldDefs, FieldDef } from '../index.js' export interface Factory { new (obj: A): T diff --git a/packages/protons-runtime/src/codecs/sfixed32.ts b/packages/protons-runtime/src/codecs/sfixed32.ts index f165b90..3958974 100644 --- a/packages/protons-runtime/src/codecs/sfixed32.ts +++ b/packages/protons-runtime/src/codecs/sfixed32.ts @@ -1,5 +1,6 @@ import { Uint8ArrayList } from 'uint8arraylist' -import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js' +import { createCodec, CODEC_TYPES } from '../codec.js' +import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js' const encodingLength: EncodingLengthFunction = function sfixed32EncodingLength () { return 4 diff --git a/packages/protons-runtime/src/codecs/sfixed64.ts b/packages/protons-runtime/src/codecs/sfixed64.ts index 68359b0..9e9a0ff 100644 --- a/packages/protons-runtime/src/codecs/sfixed64.ts +++ b/packages/protons-runtime/src/codecs/sfixed64.ts @@ -1,5 +1,6 @@ import { Uint8ArrayList } from 'uint8arraylist' -import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js' +import { createCodec, CODEC_TYPES } from '../codec.js' +import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js' const encodingLength: EncodingLengthFunction = function sfixed64EncodingLength () { return 8 diff --git a/packages/protons-runtime/src/codecs/sint32.ts b/packages/protons-runtime/src/codecs/sint32.ts index 3c72c2c..88bbb4a 100644 --- a/packages/protons-runtime/src/codecs/sint32.ts +++ b/packages/protons-runtime/src/codecs/sint32.ts @@ -1,5 +1,6 @@ import { zigzag } from '../utils/varint.js' -import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js' +import { createCodec, CODEC_TYPES } from '../codec.js' +import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js' const encodingLength: EncodingLengthFunction = function sint32EncodingLength (val) { return zigzag.encodingLength(val) diff --git a/packages/protons-runtime/src/codecs/sint64.ts b/packages/protons-runtime/src/codecs/sint64.ts index 2dc4550..ca56ce8 100644 --- a/packages/protons-runtime/src/codecs/sint64.ts +++ b/packages/protons-runtime/src/codecs/sint64.ts @@ -1,5 +1,6 @@ import { zigzag } from '../utils/big-varint.js' -import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js' +import { createCodec, CODEC_TYPES } from '../codec.js' +import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js' const encodingLength: EncodingLengthFunction = function int64EncodingLength (val) { return zigzag.encodingLength(val) diff --git a/packages/protons-runtime/src/codecs/string.ts b/packages/protons-runtime/src/codecs/string.ts index 04216dd..d544ade 100644 --- a/packages/protons-runtime/src/codecs/string.ts +++ b/packages/protons-runtime/src/codecs/string.ts @@ -1,7 +1,8 @@ import { unsigned } from '../utils/varint.js' import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' import { toString as uint8ArrayToString } from 'uint8arrays/to-string' -import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js' +import { createCodec, CODEC_TYPES } from '../codec.js' +import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js' import { Uint8ArrayList } from 'uint8arraylist' const encodingLength: EncodingLengthFunction = function stringEncodingLength (val) { diff --git a/packages/protons-runtime/src/codecs/uint32.ts b/packages/protons-runtime/src/codecs/uint32.ts index 57aa1a7..42d4153 100644 --- a/packages/protons-runtime/src/codecs/uint32.ts +++ b/packages/protons-runtime/src/codecs/uint32.ts @@ -1,5 +1,6 @@ import { unsigned } from '../utils/varint.js' -import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js' +import { createCodec, CODEC_TYPES } from '../codec.js' +import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js' const encodingLength: EncodingLengthFunction = function uint32EncodingLength (val) { return unsigned.encodingLength(val) diff --git a/packages/protons-runtime/src/codecs/uint64.ts b/packages/protons-runtime/src/codecs/uint64.ts index 4753114..f8c2925 100644 --- a/packages/protons-runtime/src/codecs/uint64.ts +++ b/packages/protons-runtime/src/codecs/uint64.ts @@ -1,5 +1,6 @@ import { unsigned } from '../utils/big-varint.js' -import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js' +import { createCodec, CODEC_TYPES } from '../codec.js' +import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js' const encodingLength: EncodingLengthFunction = function uint64EncodingLength (val) { return unsigned.encodingLength(val) diff --git a/packages/protons-runtime/src/decode.ts b/packages/protons-runtime/src/decode.ts index 99b427d..92ec257 100644 --- a/packages/protons-runtime/src/decode.ts +++ b/packages/protons-runtime/src/decode.ts @@ -1,6 +1,6 @@ import { Uint8ArrayList } from 'uint8arraylist' import { unsigned } from './utils/varint.js' -import type { Codec } from './codecs/codec.js' +import type { Codec } from './codec.js' export function decodeMessage (buf: Uint8Array, codec: Codec) { // wrap root message diff --git a/packages/protons-runtime/src/encode.ts b/packages/protons-runtime/src/encode.ts index 83f8bae..f82cfcc 100644 --- a/packages/protons-runtime/src/encode.ts +++ b/packages/protons-runtime/src/encode.ts @@ -1,4 +1,4 @@ -import type { Codec } from './codecs/codec.js' +import type { Codec } from './codec.js' import { unsigned } from './utils/varint.js' export function encodeMessage (message: T, codec: Codec) { diff --git a/packages/protons-runtime/src/index.ts b/packages/protons-runtime/src/index.ts index 7cd6656..791a4e1 100644 --- a/packages/protons-runtime/src/index.ts +++ b/packages/protons-runtime/src/index.ts @@ -1,4 +1,4 @@ -import type { Codec } from './codecs/codec.js' +import type { Codec } from './codec.js' export interface FieldDef { name: string @@ -35,3 +35,4 @@ export { sint64 } from './codecs/sint64.js' export { string } from './codecs/string.js' export { uint32 } from './codecs/uint32.js' export { uint64 } from './codecs/uint64.js' +export type { Codec } from './codec.js' diff --git a/packages/protons-runtime/tsconfig.json b/packages/protons-runtime/tsconfig.json index f296f99..13a3599 100644 --- a/packages/protons-runtime/tsconfig.json +++ b/packages/protons-runtime/tsconfig.json @@ -1,9 +1,7 @@ { "extends": "aegir/src/config/tsconfig.aegir.json", "compilerOptions": { - "outDir": "dist", - "emitDeclarationOnly": false, - "module": "ES2020" + "outDir": "dist" }, "include": [ "src", diff --git a/packages/protons/bin/protons.ts b/packages/protons/bin/protons.ts index 9cccdf2..a2ce94c 100644 --- a/packages/protons/bin/protons.ts +++ b/packages/protons/bin/protons.ts @@ -6,13 +6,13 @@ import { generate } from '../src/index.js' async function main () { const cli = meow(` Usage - $ protons source + $ protons source... Options - --output, -o Path to a directory to write transpiled typescript files into + --output, -o Path to a directory to write transpiled typescript files into Examples - $ protons ./path/to/file.proto + $ protons ./path/to/file.proto ./path/to/other/file.proto `, { importMeta: import.meta, flags: { diff --git a/packages/protons/src/index.ts b/packages/protons/src/index.ts index 2f1accc..29afe73 100644 --- a/packages/protons/src/index.ts +++ b/packages/protons/src/index.ts @@ -141,8 +141,7 @@ export namespace ${messageDef.name} { export const codec = () => { return enumeration(${messageDef.name}) } -} -` +}`.trim() } let nested = '' @@ -151,11 +150,10 @@ export namespace ${messageDef.name} { nested = '\n' nested += Object.values(messageDef.nested) .map(def => compileMessage(def, moduleDef).trim()) - .join('\n') + .join('\n\n') .split('\n') .map(line => line.trim() === '' ? '' : ` ${line}`) .join('\n') - nested += '\n' } const fields = messageDef.fields ?? {} @@ -164,18 +162,26 @@ export namespace ${messageDef.name} { moduleDef.imports.add('encodeMessage') moduleDef.imports.add('decodeMessage') moduleDef.imports.add('message') + moduleDef.importedTypes.add('Codec') - return ` + const interfaceFields = defineFields(fields, messageDef, moduleDef) + .join('\n ') + .trim() + + let interfaceDef = '' + let interfaceCodecDef = '' + + if (interfaceFields !== '') { + interfaceDef = ` export interface ${messageDef.name} { ${ defineFields(fields, messageDef, moduleDef) .join('\n ') .trim() } -} - -export namespace ${messageDef.name} {${nested} - export const codec = () => { +}` + interfaceCodecDef = ` + export const codec = (): Codec<${messageDef.name}> => { return message<${messageDef.name}>({ ${Object.entries(fields) .map(([name, fieldDef]) => { @@ -207,13 +213,21 @@ export namespace ${messageDef.name} {${nested} export const decode = (buf: Uint8Array): ${messageDef.name} => { return decodeMessage(buf, ${messageDef.name}.codec()) + }` } + + return ` +${interfaceDef} + +export namespace ${messageDef.name} { + ${`${nested}${nested !== '' && interfaceCodecDef !== '' ? '\n' : ''}${interfaceCodecDef}`.trim()} } -` +`.trimStart() } interface ModuleDef { imports: Set + importedTypes: Set types: Set compiled: string[] globals: Record @@ -222,6 +236,7 @@ interface ModuleDef { function defineModule (def: ClassDef): ModuleDef { const moduleDef: ModuleDef = { imports: new Set(), + importedTypes: new Set(), types: new Set(), compiled: [], globals: {} @@ -273,14 +288,27 @@ export async function generate (source: string, flags: any) { const def = JSON.parse(json) const moduleDef = defineModule(def) - const content = ` -/* eslint-disable import/export */ -/* eslint-disable @typescript-eslint/no-namespace */ + let lines = [ + '/* eslint-disable import/export */', + '/* eslint-disable @typescript-eslint/no-namespace */', + '' + ] + + if (moduleDef.imports.size > 0) { + lines.push(`import { ${Array.from(moduleDef.imports).join(', ')} } from 'protons-runtime'`) + } + + if (moduleDef.importedTypes.size > 0) { + lines.push(`import type { ${Array.from(moduleDef.importedTypes).join(', ')} } from 'protons-runtime'`) + } -import { ${Array.from(moduleDef.imports).join(', ')} } from 'protons-runtime' + lines = [ + ...lines, + '', + ...moduleDef.compiled + ] -${moduleDef.compiled.map(str => str.trim()).join('\n\n').trim()} -`.trim() + const content = lines.join('\n').trim() await fs.writeFile(pathWithExtension(source, '.ts'), content + '\n') } diff --git a/packages/protons/test/fixtures/basic.ts b/packages/protons/test/fixtures/basic.ts index f294002..e340908 100644 --- a/packages/protons/test/fixtures/basic.ts +++ b/packages/protons/test/fixtures/basic.ts @@ -2,6 +2,7 @@ /* eslint-disable @typescript-eslint/no-namespace */ import { encodeMessage, decodeMessage, message, string, int32 } from 'protons-runtime' +import type { Codec } from 'protons-runtime' export interface Basic { foo: string @@ -9,16 +10,18 @@ export interface Basic { } export namespace Basic { - export const codec = message({ - 1: { name: 'foo', codec: string }, - 2: { name: 'num', codec: int32 } - }) + export const codec = (): Codec => { + return message({ + 1: { name: 'foo', codec: string }, + 2: { name: 'num', codec: int32 } + }) + } export const encode = (obj: Basic): Uint8Array => { - return encodeMessage(obj, Basic.codec) + return encodeMessage(obj, Basic.codec()) } export const decode = (buf: Uint8Array): Basic => { - return decodeMessage(buf, Basic.codec) + return decodeMessage(buf, Basic.codec()) } } diff --git a/packages/protons/test/fixtures/circuit.proto b/packages/protons/test/fixtures/circuit.proto new file mode 100644 index 0000000..1eaec2e --- /dev/null +++ b/packages/protons/test/fixtures/circuit.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; + +message CircuitRelay { + + enum Status { + SUCCESS = 100; + HOP_SRC_ADDR_TOO_LONG = 220; + HOP_DST_ADDR_TOO_LONG = 221; + HOP_SRC_MULTIADDR_INVALID = 250; + HOP_DST_MULTIADDR_INVALID = 251; + HOP_NO_CONN_TO_DST = 260; + HOP_CANT_DIAL_DST = 261; + HOP_CANT_OPEN_DST_STREAM = 262; + HOP_CANT_SPEAK_RELAY = 270; + HOP_CANT_RELAY_TO_SELF = 280; + STOP_SRC_ADDR_TOO_LONG = 320; + STOP_DST_ADDR_TOO_LONG = 321; + STOP_SRC_MULTIADDR_INVALID = 350; + STOP_DST_MULTIADDR_INVALID = 351; + STOP_RELAY_REFUSED = 390; + MALFORMED_MESSAGE = 400; + } + + enum Type { // RPC identifier, either HOP, STOP or STATUS + HOP = 1; + STOP = 2; + STATUS = 3; + CAN_HOP = 4; + } + + message Peer { + required bytes id = 1; // peer id + repeated bytes addrs = 2; // peer's known addresses + } + + optional Type type = 1; // Type of the message + + optional Peer srcPeer = 2; // srcPeer and dstPeer are used when Type is HOP or STATUS + optional Peer dstPeer = 3; + + optional Status code = 4; // Status code, used when Type is STATUS +} diff --git a/packages/protons/test/fixtures/circuit.ts b/packages/protons/test/fixtures/circuit.ts new file mode 100644 index 0000000..dd32395 --- /dev/null +++ b/packages/protons/test/fixtures/circuit.ts @@ -0,0 +1,91 @@ +/* eslint-disable import/export */ +/* eslint-disable @typescript-eslint/no-namespace */ + +import { enumeration, encodeMessage, decodeMessage, message, bytes } from 'protons-runtime' +import type { Codec } from 'protons-runtime' + +export interface CircuitRelay { + type?: CircuitRelay.Type + srcPeer?: CircuitRelay.Peer + dstPeer?: CircuitRelay.Peer + code?: CircuitRelay.Status +} + +export namespace CircuitRelay { + export enum Status { + SUCCESS = 'SUCCESS', + HOP_SRC_ADDR_TOO_LONG = 'HOP_SRC_ADDR_TOO_LONG', + HOP_DST_ADDR_TOO_LONG = 'HOP_DST_ADDR_TOO_LONG', + HOP_SRC_MULTIADDR_INVALID = 'HOP_SRC_MULTIADDR_INVALID', + HOP_DST_MULTIADDR_INVALID = 'HOP_DST_MULTIADDR_INVALID', + HOP_NO_CONN_TO_DST = 'HOP_NO_CONN_TO_DST', + HOP_CANT_DIAL_DST = 'HOP_CANT_DIAL_DST', + HOP_CANT_OPEN_DST_STREAM = 'HOP_CANT_OPEN_DST_STREAM', + HOP_CANT_SPEAK_RELAY = 'HOP_CANT_SPEAK_RELAY', + HOP_CANT_RELAY_TO_SELF = 'HOP_CANT_RELAY_TO_SELF', + STOP_SRC_ADDR_TOO_LONG = 'STOP_SRC_ADDR_TOO_LONG', + STOP_DST_ADDR_TOO_LONG = 'STOP_DST_ADDR_TOO_LONG', + STOP_SRC_MULTIADDR_INVALID = 'STOP_SRC_MULTIADDR_INVALID', + STOP_DST_MULTIADDR_INVALID = 'STOP_DST_MULTIADDR_INVALID', + STOP_RELAY_REFUSED = 'STOP_RELAY_REFUSED', + MALFORMED_MESSAGE = 'MALFORMED_MESSAGE' + } + + export namespace Status { + export const codec = () => { + return enumeration(Status) + } + } + + export enum Type { + HOP = 'HOP', + STOP = 'STOP', + STATUS = 'STATUS', + CAN_HOP = 'CAN_HOP' + } + + export namespace Type { + export const codec = () => { + return enumeration(Type) + } + } + + export interface Peer { + id: Uint8Array + addrs: Uint8Array[] + } + + export namespace Peer { + export const codec = (): Codec => { + return message({ + 1: { name: 'id', codec: bytes }, + 2: { name: 'addrs', codec: bytes, repeats: true } + }) + } + + export const encode = (obj: Peer): Uint8Array => { + return encodeMessage(obj, Peer.codec()) + } + + export const decode = (buf: Uint8Array): Peer => { + return decodeMessage(buf, Peer.codec()) + } + } + + export const codec = (): Codec => { + return message({ + 1: { name: 'type', codec: CircuitRelay.Type.codec(), optional: true }, + 2: { name: 'srcPeer', codec: CircuitRelay.Peer.codec(), optional: true }, + 3: { name: 'dstPeer', codec: CircuitRelay.Peer.codec(), optional: true }, + 4: { name: 'code', codec: CircuitRelay.Status.codec(), optional: true } + }) + } + + export const encode = (obj: CircuitRelay): Uint8Array => { + return encodeMessage(obj, CircuitRelay.codec()) + } + + export const decode = (buf: Uint8Array): CircuitRelay => { + return decodeMessage(buf, CircuitRelay.codec()) + } +} diff --git a/packages/protons/test/fixtures/daemon.ts b/packages/protons/test/fixtures/daemon.ts index 9872fe4..aa7e797 100644 --- a/packages/protons/test/fixtures/daemon.ts +++ b/packages/protons/test/fixtures/daemon.ts @@ -2,6 +2,7 @@ /* eslint-disable @typescript-eslint/no-namespace */ import { enumeration, encodeMessage, decodeMessage, message, bytes, int64, string, int32 } from 'protons-runtime' +import type { Codec } from 'protons-runtime' export interface Request { type: Request.Type @@ -35,7 +36,7 @@ export namespace Request { } } - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'type', codec: Request.Type.codec() }, 2: { name: 'connect', codec: ConnectRequest.codec(), optional: true }, @@ -81,7 +82,7 @@ export namespace Response { } } - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'type', codec: Response.Type.codec() }, 2: { name: 'error', codec: ErrorResponse.codec(), optional: true }, @@ -109,7 +110,7 @@ export interface IdentifyResponse { } export namespace IdentifyResponse { - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'id', codec: bytes }, 2: { name: 'addrs', codec: bytes, repeats: true } @@ -132,7 +133,7 @@ export interface ConnectRequest { } export namespace ConnectRequest { - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'peer', codec: bytes }, 2: { name: 'addrs', codec: bytes, repeats: true }, @@ -156,7 +157,7 @@ export interface StreamOpenRequest { } export namespace StreamOpenRequest { - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'peer', codec: bytes }, 2: { name: 'proto', codec: string, repeats: true }, @@ -179,7 +180,7 @@ export interface StreamHandlerRequest { } export namespace StreamHandlerRequest { - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'addr', codec: bytes }, 2: { name: 'proto', codec: string, repeats: true } @@ -200,7 +201,7 @@ export interface ErrorResponse { } export namespace ErrorResponse { - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'msg', codec: string } }) @@ -222,7 +223,7 @@ export interface StreamInfo { } export namespace StreamInfo { - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'peer', codec: bytes }, 2: { name: 'addr', codec: bytes }, @@ -268,7 +269,7 @@ export namespace DHTRequest { } } - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'type', codec: DHTRequest.Type.codec() }, 2: { name: 'peer', codec: bytes, optional: true }, @@ -308,7 +309,7 @@ export namespace DHTResponse { } } - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'type', codec: DHTResponse.Type.codec() }, 2: { name: 'peer', codec: PeerInfo.codec(), optional: true }, @@ -331,7 +332,7 @@ export interface PeerInfo { } export namespace PeerInfo { - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'id', codec: bytes }, 2: { name: 'addrs', codec: bytes, repeats: true } @@ -367,7 +368,7 @@ export namespace ConnManagerRequest { } } - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'type', codec: ConnManagerRequest.Type.codec() }, 2: { name: 'peer', codec: bytes, optional: true }, @@ -390,7 +391,7 @@ export interface DisconnectRequest { } export namespace DisconnectRequest { - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'peer', codec: bytes } }) @@ -425,7 +426,7 @@ export namespace PSRequest { } } - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'type', codec: PSRequest.Type.codec() }, 2: { name: 'topic', codec: string, optional: true }, @@ -452,7 +453,7 @@ export interface PSMessage { } export namespace PSMessage { - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'from', codec: bytes, optional: true }, 2: { name: 'data', codec: bytes, optional: true }, @@ -478,7 +479,7 @@ export interface PSResponse { } export namespace PSResponse { - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'topics', codec: string, repeats: true }, 2: { name: 'peerIDs', codec: bytes, repeats: true } @@ -512,7 +513,7 @@ export namespace PeerstoreRequest { } } - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'type', codec: PeerstoreRequest.Type.codec() }, 2: { name: 'id', codec: bytes, optional: true }, @@ -535,7 +536,7 @@ export interface PeerstoreResponse { } export namespace PeerstoreResponse { - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'peer', codec: PeerInfo.codec(), optional: true }, 2: { name: 'protos', codec: string, repeats: true } diff --git a/packages/protons/test/fixtures/dht.ts b/packages/protons/test/fixtures/dht.ts index 2076c81..6745e51 100644 --- a/packages/protons/test/fixtures/dht.ts +++ b/packages/protons/test/fixtures/dht.ts @@ -2,6 +2,7 @@ /* eslint-disable @typescript-eslint/no-namespace */ import { encodeMessage, decodeMessage, message, bytes, string, enumeration, int32 } from 'protons-runtime' +import type { Codec } from 'protons-runtime' export interface Record { key?: Uint8Array @@ -12,20 +13,22 @@ export interface Record { } export namespace Record { - export const codec = message({ - 1: { name: 'key', codec: bytes, optional: true }, - 2: { name: 'value', codec: bytes, optional: true }, - 3: { name: 'author', codec: bytes, optional: true }, - 4: { name: 'signature', codec: bytes, optional: true }, - 5: { name: 'timeReceived', codec: string, optional: true } - }) + export const codec = (): Codec => { + return message({ + 1: { name: 'key', codec: bytes, optional: true }, + 2: { name: 'value', codec: bytes, optional: true }, + 3: { name: 'author', codec: bytes, optional: true }, + 4: { name: 'signature', codec: bytes, optional: true }, + 5: { name: 'timeReceived', codec: string, optional: true } + }) + } export const encode = (obj: Record): Uint8Array => { - return encodeMessage(obj, Record.codec) + return encodeMessage(obj, Record.codec()) } export const decode = (buf: Uint8Array): Record => { - return decodeMessage(buf, Record.codec) + return decodeMessage(buf, Record.codec()) } } @@ -49,8 +52,11 @@ export namespace Message { } export namespace MessageType { - export const codec = enumeration(MessageType) + export const codec = () => { + return enumeration(MessageType) + } } + export enum ConnectionType { NOT_CONNECTED = 'NOT_CONNECTED', CONNECTED = 'CONNECTED', @@ -59,8 +65,11 @@ export namespace Message { } export namespace ConnectionType { - export const codec = enumeration(ConnectionType) + export const codec = () => { + return enumeration(ConnectionType) + } } + export interface Peer { id?: Uint8Array addrs: Uint8Array[] @@ -68,35 +77,39 @@ export namespace Message { } export namespace Peer { - export const codec = message({ - 1: { name: 'id', codec: bytes, optional: true }, - 2: { name: 'addrs', codec: bytes, repeats: true }, - 3: { name: 'connection', codec: Message.ConnectionType.codec, optional: true } - }) + export const codec = (): Codec => { + return message({ + 1: { name: 'id', codec: bytes, optional: true }, + 2: { name: 'addrs', codec: bytes, repeats: true }, + 3: { name: 'connection', codec: Message.ConnectionType.codec(), optional: true } + }) + } export const encode = (obj: Peer): Uint8Array => { - return encodeMessage(obj, Peer.codec) + return encodeMessage(obj, Peer.codec()) } export const decode = (buf: Uint8Array): Peer => { - return decodeMessage(buf, Peer.codec) + return decodeMessage(buf, Peer.codec()) } } - export const codec = message({ - 1: { name: 'type', codec: Message.MessageType.codec, optional: true }, - 10: { name: 'clusterLevelRaw', codec: int32, optional: true }, - 2: { name: 'key', codec: bytes, optional: true }, - 3: { name: 'record', codec: bytes, optional: true }, - 8: { name: 'closerPeers', codec: Message.Peer.codec, repeats: true }, - 9: { name: 'providerPeers', codec: Message.Peer.codec, repeats: true } - }) + export const codec = (): Codec => { + return message({ + 1: { name: 'type', codec: Message.MessageType.codec(), optional: true }, + 10: { name: 'clusterLevelRaw', codec: int32, optional: true }, + 2: { name: 'key', codec: bytes, optional: true }, + 3: { name: 'record', codec: bytes, optional: true }, + 8: { name: 'closerPeers', codec: Message.Peer.codec(), repeats: true }, + 9: { name: 'providerPeers', codec: Message.Peer.codec(), repeats: true } + }) + } export const encode = (obj: Message): Uint8Array => { - return encodeMessage(obj, Message.codec) + return encodeMessage(obj, Message.codec()) } export const decode = (buf: Uint8Array): Message => { - return decodeMessage(buf, Message.codec) + return decodeMessage(buf, Message.codec()) } } diff --git a/packages/protons/test/fixtures/noise.proto b/packages/protons/test/fixtures/noise.proto new file mode 100644 index 0000000..05a78c6 --- /dev/null +++ b/packages/protons/test/fixtures/noise.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; +package pb; + +message NoiseHandshakePayload { + bytes identity_key = 1; + bytes identity_sig = 2; + bytes data = 3; +} diff --git a/packages/protons/test/fixtures/noise.ts b/packages/protons/test/fixtures/noise.ts new file mode 100644 index 0000000..855a319 --- /dev/null +++ b/packages/protons/test/fixtures/noise.ts @@ -0,0 +1,31 @@ +/* eslint-disable import/export */ +/* eslint-disable @typescript-eslint/no-namespace */ + +import { encodeMessage, decodeMessage, message, bytes } from 'protons-runtime' +import type { Codec } from 'protons-runtime' + +export namespace pb { + export interface NoiseHandshakePayload { + identityKey: Uint8Array + identitySig: Uint8Array + data: Uint8Array + } + + export namespace NoiseHandshakePayload { + export const codec = (): Codec => { + return message({ + 1: { name: 'identityKey', codec: bytes }, + 2: { name: 'identitySig', codec: bytes }, + 3: { name: 'data', codec: bytes } + }) + } + + export const encode = (obj: NoiseHandshakePayload): Uint8Array => { + return encodeMessage(obj, NoiseHandshakePayload.codec()) + } + + export const decode = (buf: Uint8Array): NoiseHandshakePayload => { + return decodeMessage(buf, NoiseHandshakePayload.codec()) + } + } +} diff --git a/packages/protons/test/fixtures/peer.ts b/packages/protons/test/fixtures/peer.ts index 676ded3..3d7c83c 100644 --- a/packages/protons/test/fixtures/peer.ts +++ b/packages/protons/test/fixtures/peer.ts @@ -2,6 +2,7 @@ /* eslint-disable @typescript-eslint/no-namespace */ import { encodeMessage, decodeMessage, message, string, bytes, bool } from 'protons-runtime' +import type { Codec } from 'protons-runtime' export interface Peer { addresses: Address[] @@ -12,7 +13,7 @@ export interface Peer { } export namespace Peer { - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'addresses', codec: Address.codec(), repeats: true }, 2: { name: 'protocols', codec: string, repeats: true }, @@ -37,7 +38,7 @@ export interface Address { } export namespace Address { - export const codec = () => { + export const codec = (): Codec
=> { return message
({ 1: { name: 'multiaddr', codec: bytes }, 2: { name: 'isCertified', codec: bool, optional: true } @@ -59,7 +60,7 @@ export interface Metadata { } export namespace Metadata { - export const codec = () => { + export const codec = (): Codec => { return message({ 1: { name: 'key', codec: string }, 2: { name: 'value', codec: bytes } diff --git a/packages/protons/test/fixtures/test.ts b/packages/protons/test/fixtures/test.ts index becfffc..54aa2a7 100644 --- a/packages/protons/test/fixtures/test.ts +++ b/packages/protons/test/fixtures/test.ts @@ -2,6 +2,7 @@ /* eslint-disable @typescript-eslint/no-namespace */ import { enumeration, encodeMessage, decodeMessage, message, string, bool, int32, int64, uint32, uint64, sint32, sint64, double, float, bytes, fixed32, fixed64, sfixed32, sfixed64 } from 'protons-runtime' +import type { Codec } from 'protons-runtime' export enum AnEnum { HERP = 'HERP', @@ -9,24 +10,27 @@ export enum AnEnum { } export namespace AnEnum { - export const codec = enumeration(AnEnum) + export const codec = () => { + return enumeration(AnEnum) + } } - export interface SubMessage { foo: string } export namespace SubMessage { - export const codec = message({ - 1: { name: 'foo', codec: string } - }) + export const codec = (): Codec => { + return message({ + 1: { name: 'foo', codec: string } + }) + } export const encode = (obj: SubMessage): Uint8Array => { - return encodeMessage(obj, SubMessage.codec) + return encodeMessage(obj, SubMessage.codec()) } export const decode = (buf: Uint8Array): SubMessage => { - return decodeMessage(buf, SubMessage.codec) + return decodeMessage(buf, SubMessage.codec()) } } @@ -52,32 +56,34 @@ export interface AllTheTypes { } export namespace AllTheTypes { - export const codec = message({ - 1: { name: 'field1', codec: bool, optional: true }, - 2: { name: 'field2', codec: int32, optional: true }, - 3: { name: 'field3', codec: int64, optional: true }, - 4: { name: 'field4', codec: uint32, optional: true }, - 5: { name: 'field5', codec: uint64, optional: true }, - 6: { name: 'field6', codec: sint32, optional: true }, - 7: { name: 'field7', codec: sint64, optional: true }, - 8: { name: 'field8', codec: double, optional: true }, - 9: { name: 'field9', codec: float, optional: true }, - 10: { name: 'field10', codec: string, optional: true }, - 11: { name: 'field11', codec: bytes, optional: true }, - 12: { name: 'field12', codec: AnEnum.codec, optional: true }, - 13: { name: 'field13', codec: SubMessage.codec, optional: true }, - 14: { name: 'field14', codec: string, repeats: true }, - 15: { name: 'field15', codec: fixed32, optional: true }, - 16: { name: 'field16', codec: fixed64, optional: true }, - 17: { name: 'field17', codec: sfixed32, optional: true }, - 18: { name: 'field18', codec: sfixed64, optional: true } - }) + export const codec = (): Codec => { + return message({ + 1: { name: 'field1', codec: bool, optional: true }, + 2: { name: 'field2', codec: int32, optional: true }, + 3: { name: 'field3', codec: int64, optional: true }, + 4: { name: 'field4', codec: uint32, optional: true }, + 5: { name: 'field5', codec: uint64, optional: true }, + 6: { name: 'field6', codec: sint32, optional: true }, + 7: { name: 'field7', codec: sint64, optional: true }, + 8: { name: 'field8', codec: double, optional: true }, + 9: { name: 'field9', codec: float, optional: true }, + 10: { name: 'field10', codec: string, optional: true }, + 11: { name: 'field11', codec: bytes, optional: true }, + 12: { name: 'field12', codec: AnEnum.codec(), optional: true }, + 13: { name: 'field13', codec: SubMessage.codec(), optional: true }, + 14: { name: 'field14', codec: string, repeats: true }, + 15: { name: 'field15', codec: fixed32, optional: true }, + 16: { name: 'field16', codec: fixed64, optional: true }, + 17: { name: 'field17', codec: sfixed32, optional: true }, + 18: { name: 'field18', codec: sfixed64, optional: true } + }) + } export const encode = (obj: AllTheTypes): Uint8Array => { - return encodeMessage(obj, AllTheTypes.codec) + return encodeMessage(obj, AllTheTypes.codec()) } export const decode = (buf: Uint8Array): AllTheTypes => { - return decodeMessage(buf, AllTheTypes.codec) + return decodeMessage(buf, AllTheTypes.codec()) } }