Skip to content

Commit c3ea5ec

Browse files
authored
fix: remove redundant defs and declare codec return type (#28)
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.
1 parent f85d3fb commit c3ea5ec

33 files changed

+369
-129
lines changed

packages/protons-runtime/src/codecs/codec.ts packages/protons-runtime/src/codec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ export interface EncodingLengthFunction<T> {
2424

2525
export interface Codec<T> {
2626
name: string
27-
type: number
27+
type: CODEC_TYPES
2828
encode: EncodeFunction<T>
2929
decode: DecodeFunction<T>
3030
encodingLength: EncodingLengthFunction<T>
3131
}
3232

33-
export function createCodec <T> (name: string, type: number, encode: EncodeFunction<T>, decode: DecodeFunction<T>, encodingLength: EncodingLengthFunction<T>): Codec<T> {
33+
export function createCodec <T> (name: string, type: CODEC_TYPES, encode: EncodeFunction<T>, decode: DecodeFunction<T>, encodingLength: EncodingLengthFunction<T>): Codec<T> {
3434
return {
3535
name,
3636
type,

packages/protons-runtime/src/codecs/bool.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js'
1+
import { createCodec, CODEC_TYPES } from '../codec.js'
2+
import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js'
23

34
const encodingLength: EncodingLengthFunction<boolean> = function boolEncodingLength () {
45
return 1

packages/protons-runtime/src/codecs/bytes.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11

22
import { Uint8ArrayList } from 'uint8arraylist'
33
import { unsigned } from '../utils/varint.js'
4-
import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js'
4+
import { createCodec, CODEC_TYPES } from '../codec.js'
5+
import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js'
56

67
const encodingLength: EncodingLengthFunction<Uint8Array> = function bytesEncodingLength (val) {
78
const len = val.byteLength

packages/protons-runtime/src/codecs/double.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Uint8ArrayList } from 'uint8arraylist'
2-
import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js'
2+
import { createCodec, CODEC_TYPES } from '../codec.js'
3+
import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js'
34

45
const encodingLength: EncodingLengthFunction<number> = function doubleEncodingLength () {
56
return 8

packages/protons-runtime/src/codecs/enum.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
import { unsigned } from '../utils/varint.js'
3-
import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, Codec, CODEC_TYPES } from './codec.js'
3+
import { createCodec, CODEC_TYPES } from '../codec.js'
4+
import type { DecodeFunction, EncodeFunction, EncodingLengthFunction, Codec } from '../codec.js'
45

56
export function enumeration <T> (e: T): Codec<T> {
67
const encodingLength: EncodingLengthFunction<string> = function enumEncodingLength (val: string) {

packages/protons-runtime/src/codecs/fixed32.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Uint8ArrayList } from 'uint8arraylist'
2-
import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js'
2+
import { createCodec, CODEC_TYPES } from '../codec.js'
3+
import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js'
34

45
const encodingLength: EncodingLengthFunction<number> = function fixed32EncodingLength () {
56
return 4

packages/protons-runtime/src/codecs/fixed64.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Uint8ArrayList } from 'uint8arraylist'
2-
import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js'
2+
import { createCodec, CODEC_TYPES } from '../codec.js'
3+
import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js'
34

45
const encodingLength: EncodingLengthFunction<bigint> = function int64EncodingLength (val) {
56
return 8

packages/protons-runtime/src/codecs/float.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Uint8ArrayList } from 'uint8arraylist'
2-
import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js'
2+
import { createCodec, CODEC_TYPES } from '../codec.js'
3+
import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js'
34

45
const encodingLength: EncodingLengthFunction<number> = function floatEncodingLength () {
56
return 4

packages/protons-runtime/src/codecs/int32.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { signed } from '../utils/varint.js'
2-
import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js'
2+
import { createCodec, CODEC_TYPES } from '../codec.js'
3+
import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js'
34

45
const encodingLength: EncodingLengthFunction<number> = function int32EncodingLength (val) {
56
return signed.encodingLength(val)

packages/protons-runtime/src/codecs/int64.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { signed } from '../utils/big-varint.js'
2-
import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js'
2+
import { createCodec, CODEC_TYPES } from '../codec.js'
3+
import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js'
34

45
const encodingLength: EncodingLengthFunction<bigint> = function int64EncodingLength (val) {
56
return signed.encodingLength(val)

packages/protons-runtime/src/codecs/message.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { unsigned } from '../utils/varint.js'
2-
import type { FieldDef, FieldDefs } from '../index.js'
3-
import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, Codec, CODEC_TYPES } from './codec.js'
2+
import { createCodec, CODEC_TYPES } from '../codec.js'
3+
import type { DecodeFunction, EncodeFunction, EncodingLengthFunction, Codec } from '../codec.js'
44
import { Uint8ArrayList } from 'uint8arraylist'
5+
import type { FieldDefs, FieldDef } from '../index.js'
56

67
export interface Factory<A, T> {
78
new (obj: A): T

packages/protons-runtime/src/codecs/sfixed32.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Uint8ArrayList } from 'uint8arraylist'
2-
import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js'
2+
import { createCodec, CODEC_TYPES } from '../codec.js'
3+
import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js'
34

45
const encodingLength: EncodingLengthFunction<number> = function sfixed32EncodingLength () {
56
return 4

packages/protons-runtime/src/codecs/sfixed64.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Uint8ArrayList } from 'uint8arraylist'
2-
import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js'
2+
import { createCodec, CODEC_TYPES } from '../codec.js'
3+
import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js'
34

45
const encodingLength: EncodingLengthFunction<bigint> = function sfixed64EncodingLength () {
56
return 8

packages/protons-runtime/src/codecs/sint32.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { zigzag } from '../utils/varint.js'
2-
import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js'
2+
import { createCodec, CODEC_TYPES } from '../codec.js'
3+
import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js'
34

45
const encodingLength: EncodingLengthFunction<number> = function sint32EncodingLength (val) {
56
return zigzag.encodingLength(val)

packages/protons-runtime/src/codecs/sint64.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { zigzag } from '../utils/big-varint.js'
2-
import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js'
2+
import { createCodec, CODEC_TYPES } from '../codec.js'
3+
import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js'
34

45
const encodingLength: EncodingLengthFunction<bigint> = function int64EncodingLength (val) {
56
return zigzag.encodingLength(val)

packages/protons-runtime/src/codecs/string.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { unsigned } from '../utils/varint.js'
22
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
33
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
4-
import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js'
4+
import { createCodec, CODEC_TYPES } from '../codec.js'
5+
import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js'
56
import { Uint8ArrayList } from 'uint8arraylist'
67

78
const encodingLength: EncodingLengthFunction<string> = function stringEncodingLength (val) {

packages/protons-runtime/src/codecs/uint32.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { unsigned } from '../utils/varint.js'
2-
import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js'
2+
import { createCodec, CODEC_TYPES } from '../codec.js'
3+
import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js'
34

45
const encodingLength: EncodingLengthFunction<number> = function uint32EncodingLength (val) {
56
return unsigned.encodingLength(val)

packages/protons-runtime/src/codecs/uint64.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { unsigned } from '../utils/big-varint.js'
2-
import { DecodeFunction, EncodeFunction, createCodec, EncodingLengthFunction, CODEC_TYPES } from './codec.js'
2+
import { createCodec, CODEC_TYPES } from '../codec.js'
3+
import type { DecodeFunction, EncodeFunction, EncodingLengthFunction } from '../codec.js'
34

45
const encodingLength: EncodingLengthFunction<bigint> = function uint64EncodingLength (val) {
56
return unsigned.encodingLength(val)

packages/protons-runtime/src/decode.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Uint8ArrayList } from 'uint8arraylist'
22
import { unsigned } from './utils/varint.js'
3-
import type { Codec } from './codecs/codec.js'
3+
import type { Codec } from './codec.js'
44

55
export function decodeMessage <T> (buf: Uint8Array, codec: Codec<T>) {
66
// wrap root message

packages/protons-runtime/src/encode.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Codec } from './codecs/codec.js'
1+
import type { Codec } from './codec.js'
22
import { unsigned } from './utils/varint.js'
33

44
export function encodeMessage <T> (message: T, codec: Codec<T>) {

packages/protons-runtime/src/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Codec } from './codecs/codec.js'
1+
import type { Codec } from './codec.js'
22

33
export interface FieldDef {
44
name: string
@@ -35,3 +35,4 @@ export { sint64 } from './codecs/sint64.js'
3535
export { string } from './codecs/string.js'
3636
export { uint32 } from './codecs/uint32.js'
3737
export { uint64 } from './codecs/uint64.js'
38+
export type { Codec } from './codec.js'

packages/protons-runtime/tsconfig.json

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
{
22
"extends": "aegir/src/config/tsconfig.aegir.json",
33
"compilerOptions": {
4-
"outDir": "dist",
5-
"emitDeclarationOnly": false,
6-
"module": "ES2020"
4+
"outDir": "dist"
75
},
86
"include": [
97
"src",

packages/protons/bin/protons.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ import { generate } from '../src/index.js'
66
async function main () {
77
const cli = meow(`
88
Usage
9-
$ protons source
9+
$ protons source...
1010
1111
Options
12-
--output, -o Path to a directory to write transpiled typescript files into
12+
--output, -o Path to a directory to write transpiled typescript files into
1313
1414
Examples
15-
$ protons ./path/to/file.proto
15+
$ protons ./path/to/file.proto ./path/to/other/file.proto
1616
`, {
1717
importMeta: import.meta,
1818
flags: {

packages/protons/src/index.ts

+44-16
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,7 @@ export namespace ${messageDef.name} {
141141
export const codec = () => {
142142
return enumeration<typeof ${messageDef.name}>(${messageDef.name})
143143
}
144-
}
145-
`
144+
}`.trim()
146145
}
147146

148147
let nested = ''
@@ -151,11 +150,10 @@ export namespace ${messageDef.name} {
151150
nested = '\n'
152151
nested += Object.values(messageDef.nested)
153152
.map(def => compileMessage(def, moduleDef).trim())
154-
.join('\n')
153+
.join('\n\n')
155154
.split('\n')
156155
.map(line => line.trim() === '' ? '' : ` ${line}`)
157156
.join('\n')
158-
nested += '\n'
159157
}
160158

161159
const fields = messageDef.fields ?? {}
@@ -164,18 +162,26 @@ export namespace ${messageDef.name} {
164162
moduleDef.imports.add('encodeMessage')
165163
moduleDef.imports.add('decodeMessage')
166164
moduleDef.imports.add('message')
165+
moduleDef.importedTypes.add('Codec')
167166

168-
return `
167+
const interfaceFields = defineFields(fields, messageDef, moduleDef)
168+
.join('\n ')
169+
.trim()
170+
171+
let interfaceDef = ''
172+
let interfaceCodecDef = ''
173+
174+
if (interfaceFields !== '') {
175+
interfaceDef = `
169176
export interface ${messageDef.name} {
170177
${
171178
defineFields(fields, messageDef, moduleDef)
172179
.join('\n ')
173180
.trim()
174181
}
175-
}
176-
177-
export namespace ${messageDef.name} {${nested}
178-
export const codec = () => {
182+
}`
183+
interfaceCodecDef = `
184+
export const codec = (): Codec<${messageDef.name}> => {
179185
return message<${messageDef.name}>({
180186
${Object.entries(fields)
181187
.map(([name, fieldDef]) => {
@@ -207,13 +213,21 @@ export namespace ${messageDef.name} {${nested}
207213
208214
export const decode = (buf: Uint8Array): ${messageDef.name} => {
209215
return decodeMessage(buf, ${messageDef.name}.codec())
216+
}`
210217
}
218+
219+
return `
220+
${interfaceDef}
221+
222+
export namespace ${messageDef.name} {
223+
${`${nested}${nested !== '' && interfaceCodecDef !== '' ? '\n' : ''}${interfaceCodecDef}`.trim()}
211224
}
212-
`
225+
`.trimStart()
213226
}
214227

215228
interface ModuleDef {
216229
imports: Set<string>
230+
importedTypes: Set<string>
217231
types: Set<string>
218232
compiled: string[]
219233
globals: Record<string, ClassDef>
@@ -222,6 +236,7 @@ interface ModuleDef {
222236
function defineModule (def: ClassDef): ModuleDef {
223237
const moduleDef: ModuleDef = {
224238
imports: new Set(),
239+
importedTypes: new Set(),
225240
types: new Set(),
226241
compiled: [],
227242
globals: {}
@@ -273,14 +288,27 @@ export async function generate (source: string, flags: any) {
273288
const def = JSON.parse(json)
274289
const moduleDef = defineModule(def)
275290

276-
const content = `
277-
/* eslint-disable import/export */
278-
/* eslint-disable @typescript-eslint/no-namespace */
291+
let lines = [
292+
'/* eslint-disable import/export */',
293+
'/* eslint-disable @typescript-eslint/no-namespace */',
294+
''
295+
]
296+
297+
if (moduleDef.imports.size > 0) {
298+
lines.push(`import { ${Array.from(moduleDef.imports).join(', ')} } from 'protons-runtime'`)
299+
}
300+
301+
if (moduleDef.importedTypes.size > 0) {
302+
lines.push(`import type { ${Array.from(moduleDef.importedTypes).join(', ')} } from 'protons-runtime'`)
303+
}
279304

280-
import { ${Array.from(moduleDef.imports).join(', ')} } from 'protons-runtime'
305+
lines = [
306+
...lines,
307+
'',
308+
...moduleDef.compiled
309+
]
281310

282-
${moduleDef.compiled.map(str => str.trim()).join('\n\n').trim()}
283-
`.trim()
311+
const content = lines.join('\n').trim()
284312

285313
await fs.writeFile(pathWithExtension(source, '.ts'), content + '\n')
286314
}

packages/protons/test/fixtures/basic.ts

+9-6
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,26 @@
22
/* eslint-disable @typescript-eslint/no-namespace */
33

44
import { encodeMessage, decodeMessage, message, string, int32 } from 'protons-runtime'
5+
import type { Codec } from 'protons-runtime'
56

67
export interface Basic {
78
foo: string
89
num: number
910
}
1011

1112
export namespace Basic {
12-
export const codec = message<Basic>({
13-
1: { name: 'foo', codec: string },
14-
2: { name: 'num', codec: int32 }
15-
})
13+
export const codec = (): Codec<Basic> => {
14+
return message<Basic>({
15+
1: { name: 'foo', codec: string },
16+
2: { name: 'num', codec: int32 }
17+
})
18+
}
1619

1720
export const encode = (obj: Basic): Uint8Array => {
18-
return encodeMessage(obj, Basic.codec)
21+
return encodeMessage(obj, Basic.codec())
1922
}
2023

2124
export const decode = (buf: Uint8Array): Basic => {
22-
return decodeMessage(buf, Basic.codec)
25+
return decodeMessage(buf, Basic.codec())
2326
}
2427
}

0 commit comments

Comments
 (0)