Skip to content

Commit

Permalink
fix: remove redundant defs and declare codec return type (#28)
Browse files Browse the repository at this point in the history
When generating code, if a namespace doesn't have any fields, don't declare an interface for it as it fails some linting checks.

Also, declare the return type of generated codec methods as we know it and it's a linting issue for some setups.
  • Loading branch information
achingbrain authored Apr 10, 2022
1 parent f85d3fb commit c3ea5ec
Show file tree
Hide file tree
Showing 33 changed files with 369 additions and 129 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ export interface EncodingLengthFunction<T> {

export interface Codec<T> {
name: string
type: number
type: CODEC_TYPES
encode: EncodeFunction<T>
decode: DecodeFunction<T>
encodingLength: EncodingLengthFunction<T>
}

export function createCodec <T> (name: string, type: number, encode: EncodeFunction<T>, decode: DecodeFunction<T>, encodingLength: EncodingLengthFunction<T>): Codec<T> {
export function createCodec <T> (name: string, type: CODEC_TYPES, encode: EncodeFunction<T>, decode: DecodeFunction<T>, encodingLength: EncodingLengthFunction<T>): Codec<T> {
return {
name,
type,
Expand Down
3 changes: 2 additions & 1 deletion packages/protons-runtime/src/codecs/bool.ts
Original file line number Diff line number Diff line change
@@ -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<boolean> = function boolEncodingLength () {
return 1
Expand Down
3 changes: 2 additions & 1 deletion packages/protons-runtime/src/codecs/bytes.ts
Original file line number Diff line number Diff line change
@@ -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<Uint8Array> = function bytesEncodingLength (val) {
const len = val.byteLength
Expand Down
3 changes: 2 additions & 1 deletion packages/protons-runtime/src/codecs/double.ts
Original file line number Diff line number Diff line change
@@ -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<number> = function doubleEncodingLength () {
return 8
Expand Down
3 changes: 2 additions & 1 deletion packages/protons-runtime/src/codecs/enum.ts
Original file line number Diff line number Diff line change
@@ -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 <T> (e: T): Codec<T> {
const encodingLength: EncodingLengthFunction<string> = function enumEncodingLength (val: string) {
Expand Down
3 changes: 2 additions & 1 deletion packages/protons-runtime/src/codecs/fixed32.ts
Original file line number Diff line number Diff line change
@@ -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<number> = function fixed32EncodingLength () {
return 4
Expand Down
3 changes: 2 additions & 1 deletion packages/protons-runtime/src/codecs/fixed64.ts
Original file line number Diff line number Diff line change
@@ -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<bigint> = function int64EncodingLength (val) {
return 8
Expand Down
3 changes: 2 additions & 1 deletion packages/protons-runtime/src/codecs/float.ts
Original file line number Diff line number Diff line change
@@ -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<number> = function floatEncodingLength () {
return 4
Expand Down
3 changes: 2 additions & 1 deletion packages/protons-runtime/src/codecs/int32.ts
Original file line number Diff line number Diff line change
@@ -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<number> = function int32EncodingLength (val) {
return signed.encodingLength(val)
Expand Down
3 changes: 2 additions & 1 deletion packages/protons-runtime/src/codecs/int64.ts
Original file line number Diff line number Diff line change
@@ -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<bigint> = function int64EncodingLength (val) {
return signed.encodingLength(val)
Expand Down
5 changes: 3 additions & 2 deletions packages/protons-runtime/src/codecs/message.ts
Original file line number Diff line number Diff line change
@@ -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<A, T> {
new (obj: A): T
Expand Down
3 changes: 2 additions & 1 deletion packages/protons-runtime/src/codecs/sfixed32.ts
Original file line number Diff line number Diff line change
@@ -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<number> = function sfixed32EncodingLength () {
return 4
Expand Down
3 changes: 2 additions & 1 deletion packages/protons-runtime/src/codecs/sfixed64.ts
Original file line number Diff line number Diff line change
@@ -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<bigint> = function sfixed64EncodingLength () {
return 8
Expand Down
3 changes: 2 additions & 1 deletion packages/protons-runtime/src/codecs/sint32.ts
Original file line number Diff line number Diff line change
@@ -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<number> = function sint32EncodingLength (val) {
return zigzag.encodingLength(val)
Expand Down
3 changes: 2 additions & 1 deletion packages/protons-runtime/src/codecs/sint64.ts
Original file line number Diff line number Diff line change
@@ -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<bigint> = function int64EncodingLength (val) {
return zigzag.encodingLength(val)
Expand Down
3 changes: 2 additions & 1 deletion packages/protons-runtime/src/codecs/string.ts
Original file line number Diff line number Diff line change
@@ -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<string> = function stringEncodingLength (val) {
Expand Down
3 changes: 2 additions & 1 deletion packages/protons-runtime/src/codecs/uint32.ts
Original file line number Diff line number Diff line change
@@ -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<number> = function uint32EncodingLength (val) {
return unsigned.encodingLength(val)
Expand Down
3 changes: 2 additions & 1 deletion packages/protons-runtime/src/codecs/uint64.ts
Original file line number Diff line number Diff line change
@@ -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<bigint> = function uint64EncodingLength (val) {
return unsigned.encodingLength(val)
Expand Down
2 changes: 1 addition & 1 deletion packages/protons-runtime/src/decode.ts
Original file line number Diff line number Diff line change
@@ -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 <T> (buf: Uint8Array, codec: Codec<T>) {
// wrap root message
Expand Down
2 changes: 1 addition & 1 deletion packages/protons-runtime/src/encode.ts
Original file line number Diff line number Diff line change
@@ -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 <T> (message: T, codec: Codec<T>) {
Expand Down
3 changes: 2 additions & 1 deletion packages/protons-runtime/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Codec } from './codecs/codec.js'
import type { Codec } from './codec.js'

export interface FieldDef {
name: string
Expand Down Expand Up @@ -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'
4 changes: 1 addition & 3 deletions packages/protons-runtime/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
{
"extends": "aegir/src/config/tsconfig.aegir.json",
"compilerOptions": {
"outDir": "dist",
"emitDeclarationOnly": false,
"module": "ES2020"
"outDir": "dist"
},
"include": [
"src",
Expand Down
6 changes: 3 additions & 3 deletions packages/protons/bin/protons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
60 changes: 44 additions & 16 deletions packages/protons/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,7 @@ export namespace ${messageDef.name} {
export const codec = () => {
return enumeration<typeof ${messageDef.name}>(${messageDef.name})
}
}
`
}`.trim()
}

let nested = ''
Expand All @@ -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 ?? {}
Expand All @@ -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]) => {
Expand Down Expand Up @@ -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<string>
importedTypes: Set<string>
types: Set<string>
compiled: string[]
globals: Record<string, ClassDef>
Expand All @@ -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: {}
Expand Down Expand Up @@ -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')
}
15 changes: 9 additions & 6 deletions packages/protons/test/fixtures/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,26 @@
/* 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
num: number
}

export namespace Basic {
export const codec = message<Basic>({
1: { name: 'foo', codec: string },
2: { name: 'num', codec: int32 }
})
export const codec = (): Codec<Basic> => {
return message<Basic>({
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())
}
}
Loading

0 comments on commit c3ea5ec

Please sign in to comment.