Skip to content

Commit

Permalink
Improved Tag Types (#89)
Browse files Browse the repository at this point in the history
* Node Typings Dependency

* Tag Type Enum Flattening

Tried to write an object to a buffer with `writeUncompressed()`, but it wasn't being allowed as a valid object, because the types of the tag key types are typed as enum members, rather than plain strings. This allows you to use both, you can either pass in the enum to the built object, or a plain object with string keys itself can now be valid as well.

https://stackoverflow.com/questions/67863114/is-there-a-way-to-have-a-switch-statement-for-an-object-with-cases-that-validate

```ts
import * as P from "prismarine-nbt";

const nbt = { /*...*/ } satisfies P.NBT;
console.log(nbt);

P.writeUncompressed(nbt);
                 // ^? This was erroring
```

* Add to Compiler/Interpreter Function Types

I wanted to figure out what the shape of `compiler` and `interpreter` are, but they don't have type definitions for the source library, from the looks of it.

* Standalone Tag Types
  • Loading branch information
Offroaders123 authored Mar 17, 2024
1 parent 945973c commit 70323d8
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 30 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"url": "https://github.com/prismarinejs/prismarine-nbt.git"
},
"devDependencies": {
"@types/node": "^20.11.24",
"chai": "^4.2.0",
"mocha": "^10.0.0",
"standard": "^17.0.0"
Expand Down
88 changes: 58 additions & 30 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,37 @@
/// <reference types="node" resolution-mode="require"/>
declare module 'prismarine-nbt'{
// @ts-expect-error - protodef is untyped
import type { Compiler, Interpreter } from "protodef";

export type Byte = { type: `${TagType.Byte}`, value: number };

export type Short = { type: `${TagType.Short}`, value: number };

export type Int = { type: `${TagType.Int}`, value: number };

export type Long = { type: `${TagType.Long}`, value: [number, number] };

export type Float = { type: `${TagType.Float}`, value: number };

export type Double = { type: `${TagType.Double}`, value: number };

export type String = { type: `${TagType.String}`, value: string };

export type List<T extends TagType> = {
type: TagType.List,
type: `${TagType.List}`,
value: { type: Tags[T]['type'], value: Tags[T]['value'][] }
};

export type Compound = { type: `${TagType.Compound}`, value: Record<string, undefined | Tags[TagType]> };

export type ByteArray = { type: `${TagType.ByteArray}`, value: Byte["value"][] };

export type ShortArray = { type: `${TagType.ShortArray}`, value: Short["value"][] };

export type IntArray = { type: `${TagType.IntArray}`, value: Int["value"][] };

export type LongArray = { type: `${TagType.LongArray}`, value: Long["value"][] };

export enum TagType {
Byte = 'byte',
Short = 'short',
Expand All @@ -21,19 +49,19 @@ declare module 'prismarine-nbt'{
}

export type Tags = {
[TagType.Byte]: { type: TagType.Byte, value: number };
[TagType.Short]: { type: TagType.Short, value: number };
[TagType.Int]: { type: TagType.Int, value: number };
[TagType.Long]: { type: TagType.Long, value: [number, number] };
[TagType.Float]: { type: TagType.Float, value: number };
[TagType.Double]: { type: TagType.Double, value: number };
[TagType.String]: { type: TagType.String, value: string };
[TagType.List]: List<TagType>
[TagType.Compound]: { type: TagType.Compound, value: Record<string, undefined | Tags[TagType]> };
[TagType.ByteArray]: { type: TagType.ByteArray, value: number[] };
[TagType.ShortArray]: { type: TagType.ShortArray, value: number[] };
[TagType.IntArray]: { type: TagType.IntArray, value: number[] };
[TagType.LongArray]: { type: TagType.LongArray, value: [number, number][] };
[TagType.Byte]: Byte;
[TagType.Short]: Short;
[TagType.Int]: Int;
[TagType.Long]: Long;
[TagType.Float]: Float;
[TagType.Double]: Double;
[TagType.String]: String;
[TagType.List]: List<TagType>;
[TagType.Compound]: Compound;
[TagType.ByteArray]: ByteArray;
[TagType.ShortArray]: ShortArray;
[TagType.IntArray]: IntArray;
[TagType.LongArray]: LongArray;
}

export type NBTFormat = 'big' | 'little' | 'littleVarint'
Expand All @@ -58,9 +86,9 @@ declare module 'prismarine-nbt'{
// Little Endian protocol
export const protoLE: any;
// Adds prismarine-nbt types to an ProtoDef compiler instance
export function addTypesToCompiler(type: NBTFormat, compiler)
export function addTypesToCompiler(type: NBTFormat, compiler: Compiler): void;
// Adds prismarine-nbt types to a ProtoDef interpreter instance
export function addTypesToInterpreter(type: NBTFormat, protodef)
export function addTypesToInterpreter(type: NBTFormat, protodef: Interpreter): void;

/** @deprecated */
export function writeUncompressed(value: NBT, little?: boolean): Buffer;
Expand All @@ -73,22 +101,22 @@ declare module 'prismarine-nbt'{
/** @deprecated */
export function parse(data: Buffer, callback: (err: Error | null, value: NBT) => any): void;

export function bool(val: number): { type: TagType.Short, value: number }
export function short (val: number): { type: TagType.Short, value: number }
export function byte<T extends number> (val: number): { type: TagType.Byte, value: number }
export function string<T extends string | string[]> (val: T): { type: TagType.String, value: T }
export function comp<T extends object | object[]> (val: T, name?: string): { type: TagType.Compound, name?: string, value: T }
export function int<T extends number | number[]> (val: T): { type: TagType.Int, value: T }
export function list<T extends string, K extends {type: T}>(value: K): { type: TagType.List; value: { type: T | 'end', value: K } }
export function float<T extends number | number[]> (value: T): { type: TagType.Float, value: T}
export function double<T extends number | number[]> (value: T): { type: TagType.Double, value: T}
export function bool(val: number): { type: `${TagType.Short}`, value: number }
export function short (val: number): { type: `${TagType.Short}`, value: number }
export function byte<T extends number> (val: number): { type: `${TagType.Byte}`, value: number }
export function string<T extends string | string[]> (val: T): { type: `${TagType.String}`, value: T }
export function comp<T extends object | object[]> (val: T, name?: string): { type: `${TagType.Compound}`, name?: string, value: T }
export function int<T extends number | number[]> (val: T): { type: `${TagType.Int}`, value: T }
export function list<T extends string, K extends {type: T}>(value: K): { type: `${TagType.List}`; value: { type: T | 'end', value: K } }
export function float<T extends number | number[]> (value: T): { type: `${TagType.Float}`, value: T}
export function double<T extends number | number[]> (value: T): { type: `${TagType.Double}`, value: T}
/**
* @param value Takes a BigInt or an array of two 32-bit integers
*/
export function long<T extends number | number[] | BigInt> (value: T): { type: TagType.Long, value: T}
export function long<T extends number | number[] | BigInt> (value: T): { type: `${TagType.Long}`, value: T}
// Arrays
export function byteArray (value: number[]): { type: TagType.ByteArray, value: number[]}
export function shortArray (value: number[]): { type: TagType.ShortArray, value: number[]}
export function intArray (value: number[]): { type: TagType.ByteArray, value: number[]}
export function longArray<T extends number[] | BigInt[]> (value: T): { type: TagType.LongArray, value: T}
export function byteArray (value: number[]): { type: `${TagType.ByteArray}`, value: number[]}
export function shortArray (value: number[]): { type: `${TagType.ShortArray}`, value: number[]}
export function intArray (value: number[]): { type: `${TagType.ByteArray}`, value: number[]}
export function longArray<T extends number[] | BigInt[]> (value: T): { type: `${TagType.LongArray}`, value: T}
}

0 comments on commit 70323d8

Please sign in to comment.