diff --git a/typescript/README.md b/typescript/README.md index 13800aeec..024c64836 100644 --- a/typescript/README.md +++ b/typescript/README.md @@ -6,7 +6,7 @@ The goal is to have types for everything, but that will take some time. Feel fre ## Using the types -All currently typed modules can be found in `/typescript/types.globals.d.ts`. +All currently typed modules can be found in `/typescript/types`. The typing is an ongoing process. If anything is still missing, you can add it! It will automatically be available in your TS files. ## Compilation diff --git a/typescript/package.json b/typescript/package.json index 8cd38ce63..8c48ce9a7 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -8,6 +8,6 @@ }, "scripts": { "build": "tsc", - "build:types": "tsc ./types/globals.d.ts" + "build:types": "tsc ./types/main.d.ts" } } diff --git a/typescript/tsconfig.json b/typescript/tsconfig.json index d36465a01..dd0f01ed4 100644 --- a/typescript/tsconfig.json +++ b/typescript/tsconfig.json @@ -11,7 +11,8 @@ "noUncheckedIndexedAccess": true, "noUnusedLocals": true, "noUnusedParameters": true, - "strict": true + "strict": true, + "typeRoots": ["./types"] }, - "include": ["../apps/**/*", "./**/*"], + "include": ["../apps/**/*", "./**/*"] } diff --git a/typescript/types/bangle.d.ts b/typescript/types/bangle.d.ts new file mode 100644 index 000000000..1e805dd41 --- /dev/null +++ b/typescript/types/bangle.d.ts @@ -0,0 +1,211 @@ +type Accel = { + x: number; + y: number; + z: number; + diff: number; + td: number; + mag: number; +}; + +type Mag = { + x: number; + y: number; + z: number; + dx: number; + dy: number; + dz: number; + heading: number; +}; + +type GPS = { + lat: number; + lon: number; + alt: number; + speed: number; + course: number; + time: Date; + stallites: number; + fix: number; + hdop: number; +}; + +type HealthStatus = { + movement: number; + steps: number; + bpm: number; + bpmConfidence: number; +}; + +type BangleOptions = { + wakeOnBTN1: boolean; + wakeOnBTN2: boolean; + wakeOnBTN3: boolean; + wakeOnFaceUp: boolean; + wakeOnTouch: boolean; + wakeOnTwist: boolean; + twistThreshold: number; + twistMaxY: number; + twistTimeout: number; + gestureStartThresh: number; + gestureEndThresh: number; + gestureInactiveCount: number; + gestureMinLength: number; + powerSave: boolean; + lockTimeout: number; + lcdPowerTimeout: number; + backlightTimeout: number; + hrmPollInterval: number; +}; + +type Optional = { + [key in keyof T]?: T[key]; +}; + +type LCDMode = "direct" | "doublebuffered" | "120x120" | "80x80"; + +declare const Bangle: { + accelRd: ((register: any, length: number) => number[]) & + ((register: any) => number); + accelWr: (register: any, data: number[] | number) => void; + appRect: { + x: number; + y: number; + w: number; + h: number; + x2: number; + y2: number; + }; + beep: (time?: number, frequency?: number) => Promise; + buzz: (time?: number, strength?: number) => Promise; + compassRd: ((register: any, length: number) => number[]) & + ((register: any) => number); + compassWr: (register: any, data: number[] | number) => void; + dbg: () => any; + drawWidgets: () => void; + F_BEEPSET: boolean; + getAccel: () => Accel; + getCompass: () => Mag; + getGPSFix: () => GPS; + getHealthStatus: (range?: "current" | "last" | "day") => HealthStatus; + getLCDMode: () => LCDMode; + getLogo: () => string; + getOptions: () => BangleOptions; + getStepCount: () => number; + hrmRd: ((register: any, length: number) => number[]) & + ((register: any) => number); + ioWr: (mask: Pin, isOn: boolean) => void; + isCharging: () => boolean; + isCompassOn: () => boolean; + isGPSOn: () => boolean; + isHRMOn: () => boolean; + isLCDOn: () => boolean; + isLocked: () => boolean; + lcdWr: (register: any, data: number[] | number) => void; + loadWidgets: () => void; + off: () => void; + on: ((event: "accel", listener: (xyz: Accel) => void) => void) & + (( + event: "aiGesture", + listener: ( + gesture: string | number | undefined, + weights: number[] + ) => void + ) => void) & + ((event: "charging", listener: (charging: boolean) => void) => void) & + (( + event: "drag", + listener: (event: { + x: number; + y: number; + dx: number; + dy: number; + b: number; + }) => void + ) => void) & + ((event: "faceUp", listener: (up: boolean) => void) => void) & + ((event: "gesture", listener: (xyz: Int8Array) => void) => void) & + ((event: "GPS", listener: (gps: GPS) => void) => void) & + (( + event: "GPS-raw", + listener: (nmea: string, dataLoss: boolean) => void + ) => void) & + ((event: "health", listener: (info: HealthStatus) => void) => void) & + (( + event: "HRM", + listener: (hrm: { + bpm: number; + confidence: number; + raw: Uint8Array; + }) => void + ) => void) & + (( + event: "HRM-raw", + listener: (hrm: { + raw: number; + filt: number; + bpm: number; + confidence: number; + }) => void + ) => void) & + ((event: "lcdPower", listener: (on: boolean) => void) => void) & + ((event: "lock", listener: (on: boolean) => void) => void) & + ((event: "mag", listener: (mag: Mag) => void) => void) & + ((event: "midnight", listener: () => void) => void) & + (( + event: "pressure", + listener: (info: { + temperature: number; + pressure: number; + altitude: number; + }) => void + ) => void) & + ((event: "step", listener: (up: number) => void) => void) & + ((event: "swipe", listener: (direction: number) => void) => void) & + (( + event: "tap", + listener: (data: { + dir: string; + double: boolean; + x: number; + y: number; + z: number; + }) => void + ) => void) & + (( + event: "touch", + listener: (button: number, xy: { x: number; y: number }) => void + ) => void) & + ((event: "twist", listener: () => void) => void); + project: (latlon: { lat: number; lon: number }) => { x: number; y: number }; + resetCompass: () => void; + setCompassPower: (isOn: boolean, appID: string) => boolean; + setGPSPower: (isOn: boolean, appID: string) => boolean; + setHRMPower: (isOn: boolean, appID: string) => boolean; + setLCDBrightness: (brightness: number) => void; + setLCDMode: (mode?: LCDMode) => void; + setLCDOffset: (y: number) => void; + setLCDPower: (isOn: boolean, appID: string) => boolean; + setLCDTimeout: (timeout: number) => void; + setLocked: (isLocked: boolean) => void; + setOptions: (options: Optional) => void; + setPollInterval: (timeout: number) => void; + setStepCount: (timeout: number) => void; + setUI: ( + type?: + | "updown" + | "leftright" + | "clock" + | "clockupdown" + | { + mode: "custom"; + back?: () => void; + touch?: (n: number, e: number) => void; + swipe?: (dir: number) => void; + drag?: (e: number) => void; + btn?: (n: number) => void; + }, + callback?: (direction: number) => void + ) => void; + showLauncher: () => void; + softOff: () => void; +}; diff --git a/typescript/types/espruino.d.ts b/typescript/types/espruino.d.ts new file mode 100644 index 000000000..c06afcc0e --- /dev/null +++ b/typescript/types/espruino.d.ts @@ -0,0 +1,59 @@ +/*~ This file declares the Espruino utility class. + *~ Reference: https://banglejs.com/reference#E + */ + +declare const E: { + showAlert: (() => Promise) & + ((message: string, title?: string) => Promise); + showMenu: (() => undefined) & + ((menu: { + // The "" value includes menu options. + ""?: { + title?: string; + back?: () => void; + selected?: number; + fontHeight?: number; + x?: number; + y?: number; + x2?: number; + y2?: number; + cB?: number; + cF?: number; + cHB?: number; + cHF?: number; + predraw?: (gfx: GraphicsApi) => void; + preflip?: (gfx: GraphicsApi, less: boolean, more: boolean) => void; + } & { + // All the other key-value pairs are menu items. + [key: string]: + | undefined + | (() => void) + | { + value: boolean; + format?: (value: boolean) => string; + onchange?: (value: boolean) => void; + } + | { + value: number; + min?: number; + max?: number; + step?: number; + format?: (value: number) => string; + onchange?: (value: number) => void; + }; + }; + }) => { + draw: () => void; + move: () => void; + select: () => void; + }); + showPrompt: (() => Promise) & + (( + message: string, + options?: { + title?: string; + buttons?: { [key: string]: T }; + img?: string; + } + ) => Promise); +}; diff --git a/typescript/types/globals.d.ts b/typescript/types/globals.d.ts index e2da49a0e..86bdb9abf 100644 --- a/typescript/types/globals.d.ts +++ b/typescript/types/globals.d.ts @@ -1,185 +1,216 @@ -// TODO all of these globals (copied from eslintrc) need to be typed at some point -/* The typing status is listed on the left of the attribute, e.g.: -status "Attribute" - - // Methods and Fields at https://banglejs.com/reference - "Array": "readonly", - "ArrayBuffer": "readonly", - "ArrayBufferView": "readonly", -started "Bangle": "readonly", - "BluetoothDevice": "readonly", - "BluetoothRemoteGATTCharacteristic": "readonly", - "BluetoothRemoteGATTServer": "readonly", - "BluetoothRemoteGATTService": "readonly", - "Boolean": "readonly", - "console": "readonly", - "DataView": "readonly", - "Date": "readonly", - "E": "readonly", - "Error": "readonly", - "Flash": "readonly", - "Float32Array": "readonly", - "Float64Array": "readonly", - "fs": "readonly", - "Function": "readonly", -started "Graphics": "readonly", -done "heatshrink": "readonly", - "I2C": "readonly", - "Int16Array": "readonly", - "Int32Array": "readonly", - "Int8Array": "readonly", - "InternalError": "readonly", - "JSON": "readonly", - "Math": "readonly", - "Modules": "readonly", - "NRF": "readonly", - "Number": "readonly", - "Object": "readonly", - "OneWire": "readonly", - "Pin": "readonly", - "process": "readonly", - "Promise": "readonly", - "ReferenceError": "readonly", - "RegExp": "readonly", - "Serial": "readonly", - "SPI": "readonly", - "Storage": "readonly", - "StorageFile": "readonly", - "String": "readonly", - "SyntaxError": "readonly", - "tensorflow": "readonly", - "TFMicroInterpreter": "readonly", - "TypeError": "readonly", - "Uint16Array": "readonly", - "Uint24Array": "readonly", - "Uint32Array": "readonly", - "Uint8Array": "readonly", - "Uint8ClampedArray": "readonly", - "Waveform": "readonly", - // Methods and Fields at https://banglejs.com/reference - "analogRead": "readonly", - "analogWrite": "readonly", - "arguments": "readonly", - "atob": "readonly", - "Bluetooth": "readonly", - "BTN": "readonly", - "BTN1": "readonly", - "BTN2": "readonly", - "BTN3": "readonly", - "BTN4": "readonly", - "BTN5": "readonly", - "btoa": "readonly", - "changeInterval": "readonly", - "clearInterval": "readonly", - "clearTimeout": "readonly", - "clearWatch": "readonly", - "decodeURIComponent": "readonly", - "digitalPulse": "readonly", - "digitalRead": "readonly", - "digitalWrite": "readonly", - "dump": "readonly", - "echo": "readonly", - "edit": "readonly", - "encodeURIComponent": "readonly", - "eval": "readonly", - "getPinMode": "readonly", - "getSerial": "readonly", - "getTime": "readonly", - "global": "readonly", - "HIGH": "readonly", - "I2C1": "readonly", - "Infinity": "readonly", - "isFinite": "readonly", - "isNaN": "readonly", - "LED": "readonly", - "LED1": "readonly", - "LED2": "readonly", - "load": "readonly", - "LoopbackA": "readonly", - "LoopbackB": "readonly", - "LOW": "readonly", - "NaN": "readonly", - "parseFloat": "readonly", - "parseInt": "readonly", - "peek16": "readonly", - "peek32": "readonly", - "peek8": "readonly", - "pinMode": "readonly", - "poke16": "readonly", - "poke32": "readonly", - "poke8": "readonly", - "print": "readonly", -started "require": "readonly", - "reset": "readonly", - "save": "readonly", - "Serial1": "readonly", - "setBusyIndicator": "readonly", - "setInterval": "readonly", - "setSleepIndicator": "readonly", - "setTime": "readonly", - "setTimeout": "readonly", - "setWatch": "readonly", - "shiftOut": "readonly", - "SPI1": "readonly", - "Terminal": "readonly", - "trace": "readonly", - "VIBRATE": "readonly", - // Aliases and not defined at https://banglejs.com/reference -done "g": "readonly", -done "WIDGETS": "readonly" +/*~ This file declares the Espruino globals. + *~ Reference: https://banglejs.com/reference#_global */ -// ambient JS definitions +/* Note: The following don't have to be declared as they are + * already part of regular JavaScript: + * btoa + * clearInterval + * clearTimeout + * decodeURIComponent + * encodeURIComponent + * eval + * Infinity + * isFinite + * isNaN + * NaN + * parseFloat + * parseInt + * setInterval + * setTimeout + */ -declare const require: ((module: 'heatshrink') => { +// Pins +declare type Pin = number; +declare type PinMode = + | "analog" + | "input" + | "intupt_pullup" + | "intupt_pulldown" + | "output" + | "opendrain" + | "af_output" + | "af_opendrain"; + +declare const BTN: 24; +declare const BTN1: 24; +declare const BTN2: 22; +declare const BTN3: 23; +declare const BTN4: 11; +declare const BTN5: 16; +declare const VIBRATE: 13; + +declare function getPinMode(pin: Pin): PinMode; +declare function pinMode( + pin: Pin, + mode?: PinMode | "auto", + automatic?: boolean +): void; + +// Analog pins + +/** + * Get the analog value of the given pin. + * This is different to Arduino which only returns an integer between 0 and 1023. + * However only pins connected to an ADC will work (see the datasheet). + * **Note**: if you didn't call `pinMode` beforehand then this function will also reset pin's state to "analog". + * @param {number} pin - The pin to use. + * @returns {number} The analog Value of the Pin between 0 and 1. + * @url https://banglejs.com/reference#l__global_analogRead + */ +declare function analogRead(pin: Pin): number; + +/** + * Set the analog Value of a pin. It will be output using PWM. + * **Note**: if you didn't call pinMode beforehand then this function will also reset pin's state to "output". + * @param {number} pin - The pin to use. + * @param {number} value - A value between 0 and 1. + * @param {object} [options] - Additonal options. + * @param {number} [options.freq] - Pulse frequency in Hz, e.g. 10 - specifying a frequency will force PWM output, even if the pin has a DAC. + * @param {boolean} [options.soft] - If true software PWM is used if hardware is not available. + * @param {boolean} [options.forceSoft] - If true software PWM is used even if hardware PWM or a DAC is available. + */ +declare function analogWrite( + pin: Pin, + value: number, + options?: { freq?: number; soft?: boolean; forceSoft?: boolean } +): void; + +// Digital pins +declare const HIGH: 1; + +declare const LOW: 0; + +declare function digitalPulse(pin: Pin, value: boolean, time: number): void; + +declare function digitalRead(pin: Pin | Pin[]): number; + +declare function digitalWrite(pin: Pin, value: boolean): void; +declare function digitalWrite(pin: Pin[], value: number): void; +declare function digitalWrite( + pin: { + write: (value: boolean) => void; + }, + value: boolean +): void; + +// Other globals +declare function atob(base64Data: string): string; + +declare function btoa(binaryData: string): string; + +declare function changeInterval(id: number, time: number): void; + +declare function dump(): void; + +declare function echo(echoOn: boolean): void; + +declare function edit(funcName: string | Function): void; + +declare function getSerial(): number; + +declare function getTime(): number; + +declare const global: any; //TODO define better + +declare const I2C1: I2C; + +declare function load(file?: string): void; + +declare function peek8(address: number, count?: 1): number; +declare function peek8(address: number, count: number): Uint8Array; + +declare function peek16(address: number, count?: 1): number; +declare function peek16(address: number, count: number): Uint16Array; + +declare function peek32(address: number, count?: 1): number; +declare function peek32(address: number, count: number): Uint32Array; + +declare function poke8(address: number, value: number): void; + +declare function poke16(address: number, value: number): void; + +declare function poke32(address: number, value: number): void; + +declare function print(...args: any[]): void; + +declare const Serial1: Serial; + +declare const Bluetooth: Serial; + +declare const LoopbackA: Serial; + +declare const LoopbackB: Serial; + +declare function require(module: "heatshrink"): { decompress: (compressedString: string) => string; -}) & // TODO add more - ((module: 'otherString') => {}); - -// ambient bangle.js definitions - -declare const Bangle: { - // functions - buzz: (duration?: number, intensity?: number) => Promise; - drawWidgets: () => void; - isCharging: () => boolean; - // events - on(event: 'charging', listener: (charging: boolean) => void): void; - // TODO add more }; +declare function require(module: "Storage"): Storage; +declare type Module = "heatshrink" | "Storage"; -declare type Image = { - width: number; - height: number; - bpp?: number; - buffer: ArrayBuffer | string; - transparent?: number; - palette?: Uint16Array; -}; +declare function reset(clearFlash?: true): void; -declare type GraphicsApi = { - reset: () => GraphicsApi; - flip: () => void; - setColor: (color: string) => GraphicsApi; // TODO we can most likely type color more usefully than this - drawImage: ( - image: string | Image | ArrayBuffer, - xOffset: number, - yOffset: number, +declare function setInterval(id: any): void; + +declare function setBusyIndicator(pin?: Pin): void; + +declare function setSleepIndicator(pin?: Pin): void; + +declare function setTime(time: number): void; + +type Data = + | number + | string + | Array + | ArrayBuffer + | { data: Data; count: number } + | { callback: () => Data }; + +declare function shiftOut( + pins: Pin | Pin[], + options: { clk: Pin; repeat?: number }, + data: Data +): void; + +declare const SPI1: SPIInstance; + +declare const Terminal: Serial; + +declare function trace(root?: number): void; + +// Watches +declare function clearWatch(id?: number): void; +declare const setWatch: (( + callback: + | ((obj: { state: boolean; time: number; lastTime: number }) => void) + | string, + pin: number, + options?: + | boolean + | number + | { + repeat?: boolean; + edge?: "rising" | "falling" | "both"; + debounce?: number; + irq?: boolean; + } +) => number) & + // If a data option is specified, the callback will also have one. + (( + callback: + | ((obj: { + state: boolean; + time: number; + lastTime: number; + data: any; // TODO: Specify data type + }) => void) + | string, + pin: number, options?: { - rotate?: number; - scale?: number; + data: number; + repeat?: boolean; + edge?: "rising" | "falling" | "both"; + debounce?: number; + irq?: boolean; } - ) => GraphicsApi; - // TODO add more -}; - -declare const Graphics: GraphicsApi; -declare const g: GraphicsApi; - -type WidgetArea = 'tl' | 'tr' | 'bl' | 'br'; -declare type Widget = { - area: WidgetArea; - width: number; - draw: (this: { x: number; y: number }) => void; -}; -declare const WIDGETS: { [key: string]: Widget }; + ) => number); diff --git a/typescript/types/graphics.d.ts b/typescript/types/graphics.d.ts new file mode 100644 index 000000000..05f24cc18 --- /dev/null +++ b/typescript/types/graphics.d.ts @@ -0,0 +1,266 @@ +/*~ This file declares the Graphics class. + *~ Reference: https://banglejs.com/reference#Graphics + */ + +type Image = { + width: number; + height: number; + buffer: ArrayBuffer | string; + bpp?: number; + transparent?: number; + palette?: Uint16Array; +}; + +type Theme = { + fg: number; + bg: number; + fg2: number; + bg2: number; + fgH: number; + bgH: number; + dark: boolean; +}; + +type Layer = { + x: number; + y: number; + image: string | Image | ArrayBuffer; + scale?: number; + rotate?: number; + center?: boolean; + repeat?: boolean; + nobounds?: boolean; +}; + +type GraphicsApi = { + asBMP: () => string | undefined; + + asImage: ((type: "object" | undefined) => object) & + ((type: "string") => string); + + asURL: () => string | undefined; + + blit: (options: { + x1: number; + y1: number; + w: number; + h: number; + x2: number; + y2: number; + setModified?: boolean; + }) => GraphicsApi; + + buffer: ArrayBuffer; + + clear: (reset?: boolean) => GraphicsApi; + + clearRect: ((x1: number, y1: number, x2: number, y2: number) => GraphicsApi) & + ((options: { + x: number; + y: number; + x2: number; + y2: number; + }) => GraphicsApi) & + ((options: { x: number; y: number; w: number; h: number }) => GraphicsApi); + + createArrayBuffer: ( + width: number, + height: number, + bpp: number, + options?: { + zigzag?: boolean; + vertical_byte?: boolean; + msb?: boolean; + interleavex?: boolean; + color_order?: "rgb" | "rbg" | "grb" | "gbr" | "brg" | "bgr"; + } + ) => GraphicsApi; + + createCallback: ( + width: number, + height: number, + bpp: number, + callback: ((x: number, y: number, colour: number) => void) & { + setPixel: (x: number, y: number, colour: number) => void; + fillRect: ( + x1: number, + y1: number, + x2: number, + y2: number, + colour: number + ) => void; + } + ) => GraphicsApi; + + createImage: (str: string) => Image; + + drawCircle: (x: number, y: number, radius: number) => GraphicsApi; + + drawCircleAA: (x: number, y: number, radius: number) => GraphicsApi; + + drawEllipse: (x1: number, y1: number, x2: number, y2: number) => GraphicsApi; + + drawImage: ( + image: string | Image | ArrayBuffer, + xOffset: number, + yOffset: number, + options?: { + rotate?: number; + scale?: number; + frame?: number; + } + ) => GraphicsApi; + + drawImages: ( + layers: [Layer?, Layer?, Layer?], + options?: { + x: number; + y: number; + width: number; + height: number; + } + ) => GraphicsApi; + + drawLine: (x1: number, y1: number, x2: number, y2: number) => GraphicsApi; + + drawLineAA: (x1: number, y1: number, x2: number, y2: number) => GraphicsApi; + + // TODO: Somehow define that poly must have an even number of items + drawPoly: (poly: number[], closed?: boolean) => GraphicsApi; + + drawPolyAA: (poly: number[], closed?: boolean) => GraphicsApi; + + drawRect: (x1: number, y1: number, x2: number, y2: number) => GraphicsApi; + + drawString: ( + str: string | number | boolean, + x: number, + y: number, + solid?: boolean + ) => GraphicsApi; + + dump: () => void; + + fillCircle: (x: number, y: number, radius: number) => GraphicsApi; + + fillEllipse: (x1: number, y1: number, x2: number, y2: number) => GraphicsApi; + + fillPoly: (poly: number[], closed?: boolean) => GraphicsApi; + + fillPolyAA: (poly: number[], closed?: boolean) => GraphicsApi; + + fillRect: (x1: number, y1: number, x2: number, y2: number) => GraphicsApi; + + flip: (all?: boolean) => GraphicsApi; + + getBgColor: () => number; + + getBPP: () => number; + + getColor: () => number; + + getFont: () => string; + + getFontHeight: () => number; + + getFonts: () => string[]; + + getHeight: () => number; + + getInstance: () => GraphicsApi | undefined; + + getModified: ( + reset?: boolean + ) => { x1: number; y1: number; x2: number; y2: number } | undefined; + + getPixel: (x: number, y: number) => number; + + getWidth: () => number; + + imageMetrics: (image: string | GraphicsApi | Image | ArrayBuffer) => + | { + width: number; + height: number; + bpp: number; + transparent: number; + } + | undefined; + + lineTo: (x: number, y: number) => GraphicsApi; + + moveTo: (x: number, y: number) => GraphicsApi; + + quadraticBezier: ( + vertices: [ + x0: number, + y0: number, + x1: number, + y1: number, + x2: number, + y2: number + ], + points?: number + ) => number[]; + + reset: () => GraphicsApi; + + scroll: (x: number, y: number) => GraphicsApi; + + setBgColor: ((color: string) => GraphicsApi) & + ((color: number) => GraphicsApi) & + ((r: number, g: number, b: number) => GraphicsApi); + + setClipRect: (x1: number, y1: number, x2: number, y2: number) => GraphicsApi; + + setColor: ((color: string) => GraphicsApi) & + ((color: number) => GraphicsApi) & + ((r: number, g: number, b: number) => GraphicsApi); + + setFont: (name?: string, size?: number) => GraphicsApi; + + setFontAlign: ( + x: -1 | 0 | 1, + y: -1 | 0 | 1, + rotation?: 0 | 1 | 2 | 3 + ) => GraphicsApi; + + setFontBitmap: () => GraphicsApi; + + setFontCustom: ( + bitmap: ArrayBuffer, + firstChar: number, + width: number | string, + height: number + ) => GraphicsApi; + + setFontVector: (size: number) => GraphicsApi; + + setPixel: ( + x: number, + y: number, + colour: number | string | undefined + ) => GraphicsApi; + + setRotation: (rotation: 0 | 1 | 2 | 3, reflect?: boolean) => GraphicsApi; + + setTheme: (theme: Theme) => GraphicsApi; + + stringMetrics: (str: string) => { width: number; height: number }; + + stringWidth: (str: string) => number; + + theme: Theme; + + toColor: ((color: string) => number) & + ((color: number) => number) & + ((r: number, g: number, b: number) => number); + + transformVertices: ( + verts: number[], + transformation: + | { x?: number; y?: number; scale?: number; rotate?: number } + | [number, number, number, number, number, number] // 2D transformation matrix + ) => number[]; + + wrapString: (str: string, maxWidth: number) => string[]; +}; diff --git a/typescript/types/i2c.d.ts b/typescript/types/i2c.d.ts new file mode 100644 index 000000000..a45ea4bcc --- /dev/null +++ b/typescript/types/i2c.d.ts @@ -0,0 +1,7 @@ +/*~ This file declares the I2c class. + *~ Reference: https://banglejs.com/reference#I2C + */ + +declare class I2C { + constructor(); +} diff --git a/typescript/types/main.d.ts b/typescript/types/main.d.ts new file mode 100644 index 000000000..a4c08b312 --- /dev/null +++ b/typescript/types/main.d.ts @@ -0,0 +1,26 @@ +/*~ These are the type declarations for Espruino on the Bangle.JS. + *~ Reference: https://banglejs.com/reference + */ + +/// +/// +/// +/// +/// +/// +/// +/// + +declare const Graphics: GraphicsApi; +declare const g: GraphicsApi; + +type WidgetArea = "tl" | "tr" | "bl" | "br"; +type Widget = { + area: WidgetArea; + width: number; + draw: (this: { x: number; y: number }) => void; +}; + +declare const WIDGETS: { [key: string]: Widget }; + +declare let exports: any; diff --git a/typescript/types/package.json b/typescript/types/package.json new file mode 100644 index 000000000..7259e2ab0 --- /dev/null +++ b/typescript/types/package.json @@ -0,0 +1,5 @@ +{ + "name": "banglejs", + "version": "1.0.0", + "typings": "main.d.ts" +} diff --git a/typescript/types/serial.d.ts b/typescript/types/serial.d.ts new file mode 100644 index 000000000..73702c94c --- /dev/null +++ b/typescript/types/serial.d.ts @@ -0,0 +1 @@ +declare type Serial = {}; diff --git a/typescript/types/spi.d.ts b/typescript/types/spi.d.ts new file mode 100644 index 000000000..5ca3e7bee --- /dev/null +++ b/typescript/types/spi.d.ts @@ -0,0 +1,24 @@ +declare type SPI = { + find(pin: Pin): SPIInstance | undefined; + new (): SPIInstance; +}; + +type TOrArray = T | TOrArray[]; +type TArrObj = T | TArrObj[] | { data: TArrObj; count: number }; +type NumStrArr = TOrArray; + +declare type SPIInstance = { + send(data: TArrObj, nss_pin: number): any; + send4bit(data: NumStrArr, bit0: number, bit1: number, nss_pin: number): void; + send8bit(data: NumStrArr, bit0: number, bit1: number, nss_pin: number): void; + setup(options: { + sck?: Pin; + miso?: Pin; + mosi?: Pin; + baud?: number; + mode?: 0 | 1 | 2 | 3; + order?: "msb" | "lsb"; + bits?: number; + }): void; + write(...data: Array): void; +}; diff --git a/typescript/types/storage.d.ts b/typescript/types/storage.d.ts new file mode 100644 index 000000000..d71172ac9 --- /dev/null +++ b/typescript/types/storage.d.ts @@ -0,0 +1,29 @@ +type FileData = string | Array | Object; + +declare interface Storage { + compact: () => void; + erase: (name: string) => void; + eraseAll: () => void; + getFree: () => number; + hash: (regex?: RegExp) => number; // More specifically it returns Uint32 + list: (regex?: RegExp, filter?: { sf: boolean }) => string[]; + open: (name: string, mode: "r" | "w" | "a") => StorageFile; + read: (name: string, offset?: number, length?: number) => string | undefined; + readArrayBuffer: (name: string) => ArrayBuffer | undefined; + readJSON: (name: string, noExceptions?: boolean) => any; + write: ( + name: string, + data: FileData, + offset?: number, + size?: number + ) => boolean; + writeJSON: (name: string, data: any) => boolean; +} + +declare interface StorageFile { + erase: () => void; + getLength: () => number; + read: (len: number) => string | undefined; + readLine: () => string | undefined; + write: (data: FileData) => string; +}