diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..d3c24ec --- /dev/null +++ b/index.d.ts @@ -0,0 +1,154 @@ +declare module 'restructure' { + export class DecodeStream { + buffer: Buffer; + view: DataView; + pos: number; + + constructor(buffer: Buffer); + + readString(length: number, encoding = 'ascii'): Buffer; + readBuffer(length: number): Buffer; + // TODO: other read... methods + } + + export class EncodeStream { + buffer: Buffer; + view: DataView; + pos: number; + length: number; + + constructor(buffer: Buffer); + + writeBuffer(buffer: Buffer): void; + writeString(string: string, encoding = 'ascii'): void; + // TODO: other write... methods + + fill(val: Buffer, length: number); + } + + class Base { + constructor(...args: any); + fromBuffer(buffer: Buffer): T; + toBuffer(value: T): Buffer; + + decode(stream: r.DecodeStream): T; + encode(stream: r.EncodeStream, val: T): void; + size(): number; + } + export type BaseType = typeof Base; + + class BufferT extends Base {} + export { BufferT as Buffer }; + + type BaseOf = T extends Base ? U : never; + + export type LengthArray = N extends number + ? number extends N + ? T[] + : R['length'] extends N + ? R + : LengthArray + : T[]; + + // TODO: Fix array fo structs with computed properties type + export class Array extends Base< + LengthArray, N> + > { + type: T; + length?: N; + lengthType?: 'count' | 'bytes'; + + constructor(type: T, length?: N, lengthType?: 'count' | 'bytes'); + } + export class Bitfield> extends Base {} + + export class Boolean extends Base {} + + export class Enum extends Base< + T[number] | number + > { + constructor(type: Base, options: T); + } + + export class LazyArray extends Base {} + + class NumberT extends Base {} + export { NumberT as Number }; + + export class Fixed extends Number {} + + export class Optional extends Base { + constructor(type: Base, condition?: boolean); + } + + export class Pointer extends Base {} + + export class VoidPointer { + constructor(type: any, value: any); + } + + export class Reserved extends Base {} + + class StringT extends Base {} + export { StringT as String }; + + export type StructType> = { + [K in keyof T]: T[K] extends Base + ? U + : T[K] extends () => infer V + ? V + : T[K]; + }; + + export type StructFields> = { + [K in keyof T]: T[K] extends (...args: any[]) => infer V + ? ( + this: StructType>, + ctx: StructType>, + parent: unknown + ) => V + : T[K]; + }; + + type StructToBuffer> = StructType<{ + [K in keyof T as T[K] extends () => unknown ? never : K]: T[K]; + }>; + + export class Struct> extends Base< + StructType + > { + fields: StructFields; + constructor(fields: StructFields); + + toBuffer(struct: StructToBuffer): Buffer; + } + + export class VersionedStruct extends Base {} + + export const uint8: NumberT; + export const uint16be: NumberT; + export const uint16 = uint16be; + export const uint16le: NumberT; + export const uint24be: NumberT; + export const uint24 = uint24be; + export const uint24le: NumberT; + export const uint32be: NumberT; + export const uint32 = uint32be; + export const uint32le: NumberT; + export const int8: NumberT; + export const int16be: NumberT; + export const int16 = int16be; + export const int16le: NumberT; + export const int24be: NumberT; + export const int24 = int24be; + export const int24le: NumberT; + export const int32be: NumberT; + export const int32 = int32be; + export const int32le: NumberT; + export const floatbe: NumberT; + export const float = floatbe; + export const floatle: NumberT; + export const doublebe: NumberT; + export const double = doublebe; + export const doublele: NumberT; +} diff --git a/package.json b/package.json index 2da168f..d27d700 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "main": "./dist/main.cjs", "module": "./index.js", "source": "./index.js", + "types": "./index.d.ts", "exports": { "import": "./index.js", "require": "./dist/main.cjs" diff --git a/src/Struct.js b/src/Struct.js index 335eaf1..2325697 100644 --- a/src/Struct.js +++ b/src/Struct.js @@ -9,7 +9,7 @@ export class Struct extends Base { decode(stream, parent, length = 0) { const res = this._setup(stream, parent, length); - this._parseFields(stream, res, this.fields); + this._parseFields(stream, res, this.fields, parent); if (this.process != null) { this.process.call(res, stream); @@ -31,12 +31,12 @@ export class Struct extends Base { return res; } - _parseFields(stream, res, fields) { + _parseFields(stream, res, fields, parent) { for (let key in fields) { var val; const type = fields[key]; if (typeof type === 'function') { - val = type.call(res, res); + val = type.call(res, res, parent); } else { val = type.decode(stream, res); }