Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,10 @@ for ( var i = 0, l = users.length; i < l; i++ ) {
})
}
```

## Development
### Generate new TypeScript definitions
```sh
$ npx -p typescript tsc lib/**/*.js --declaration --allowJs --emitDeclarationOnly --outDir types
```

72 changes: 69 additions & 3 deletions lib/pushover.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ var qs = require('querystring')
var pUrl = 'https://api.pushover.net/1/messages.json'
var path = require('path')

/**
* Sets default values for missing properties in the object.
* @param {object} o - The object containing optional properties.
* @returns {object} The object with default properties set.
*/
function setDefaults (o) {
var def = [
'device',
Expand All @@ -28,6 +33,11 @@ function setDefaults (o) {
return o
}

/**
* Loads an image from the specified file path.
* @param {string} imgPath - The file path of the image to load.
* @returns {object} An object containing the image name and data.
*/
function loadImage(imgPath) {
var o = {}
o.name = path.basename(imgPath)
Expand All @@ -36,6 +46,13 @@ function loadImage(imgPath) {
}


/**
* Converts a request string into a multipart form-data payload.
* @param {string} rs - The request string to convert.
* @param {string} b - The boundary string used for multipart form-data.
* @param {object} [imgObj] - The optional image object containing the image data and metadata.
* @returns {Buffer} The multipart payload as a Buffer object.
*/
function reqString2MP(rs, b, imgObj) {
var a = []
var parts = []
Expand Down Expand Up @@ -81,6 +98,17 @@ function reqString2MP(rs, b, imgObj) {
return payload
}

/**
* Creates a new Pushover instance.
* @class
* @param {object} opts - The options for Pushover.
* @param {string} opts.token - The Pushover API token.
* @param {string} opts.user - The user key for sending messages.
* @param {object} [opts.httpOptions] - Optional HTTP options.
* @param {boolean} [opts.debug] - Enable debug logging.
* @param {function} [opts.onerror] - Custom error handler.
* @param {boolean} [opts.update_sounds] - Automatically update sounds.
*/
function Pushover (opts) {
var self = this
this.boundary = "--" + Math.random().toString(36).substring(2)
Expand Down Expand Up @@ -129,6 +157,12 @@ function Pushover (opts) {
}


/**
* Handles errors from Pushover API responses.
* @param {string|object} d - The response data from the API.
* @param {object} res - The HTTP response object.
* @throws {Error} Throws an error if there are API errors and no error handler is provided.
*/
Pushover.prototype.errors = function (d, res) {
if (typeof d === 'string') {
try {
Expand All @@ -148,6 +182,9 @@ Pushover.prototype.errors = function (d, res) {
}
}

/**
* Updates the list of available Pushover sounds.
*/
Pushover.prototype.updateSounds = function () {
var self = this
var data = ''
Expand Down Expand Up @@ -176,6 +213,11 @@ Pushover.prototype.updateSounds = function () {
req.end()
}

/**
* Sends a message using Pushover.
* @param {Message} obj - The message to send.
* @param {PushoverCallback} fn - The callback function that handles the response.
*/
Pushover.prototype.send = function (obj, fn) {
var self = this
var o = url.parse(pUrl)
Expand Down Expand Up @@ -209,7 +251,7 @@ Pushover.prototype.send = function (obj, fn) {
mp = reqString2MP(reqString, self.boundary, obj.file)
}
} else {
mp = reqString2MP(reqString, self.boundary)
mp = reqString2MP(reqString, self.boundary)
}

o.headers = {
Expand Down Expand Up @@ -262,8 +304,8 @@ Pushover.prototype.send = function (obj, fn) {
if (fn) {
fn(err)
}
// In the tests the "end" event did not get emitted if "error" was emitted,
// but to be sure that the callback is not get called twice, null the callback function
// In the tests the "end" event did not get emitted if "error" was emitted,
// but to be sure that the callback is not called twice, null the callback function
fn = null
})

Expand All @@ -275,4 +317,28 @@ Pushover.prototype.send = function (obj, fn) {
req.end()
}

/**
* A callback function that handles the result of the Pushover send operation.
* @callback PushoverCallback
* @param {Error|null} error - The error object if the operation failed, or null if successful.
* @param {any} result - The result of the operation, can be any type.
*/

/**
* @typedef {Object} Message
* @property {string} message - The message to send
* @property {string} [token] - The API token.
* @property {string} [user] - The user key.
* @property {string|object} [file] - A file path or binary image attachment to send with the message
* @property {string} [device] - The name of one of your devices to send just to that device instead of all devices
* @property {string} [html] - Set to 1 to enable HTML parsing
* @property {string} [priority] - A value of -2, -1, 0 (default), 1, or 2
* @property {string} [sound] - The name of a supported sound to override your default sound choice
* @property {string} [timestamp] - A Unix timestamp of a time to display instead of when our API received it
* @property {string} [title] - Your message's title, otherwise your app's name is used
* @property {string} [ttl] - A number of seconds that the message will live, before being deleted automatically
* @property {string} [url] - A supplementary URL to show with your message
* @property {string} [url_title] - A title for the URL specified as the url parameter, otherwise just the URL is shown
*/

exports = module.exports = Pushover
22 changes: 22 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
// Change this to match your project
"include": ["lib/**/*"],
"compilerOptions": {
// Tells TypeScript to read JS files, as
// normally they are ignored as source files
"allowJs": true,
// Generate d.ts files
"declaration": true,
// This compiler run should
// only output d.ts files
"emitDeclarationOnly": true,
// Types should go into this directory.
// Removing this would place the .d.ts files
// next to the .js files
"outDir": "dist",
// go to js file when using IDE functions like
// "Go to Definition" in VSCode
"declarationMap": true
}
}

149 changes: 149 additions & 0 deletions types/pushover.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
export = Pushover;
/**
* Creates a new Pushover instance.
* @class
* @param {object} opts - The options for Pushover.
* @param {string} opts.token - The Pushover API token.
* @param {string} opts.user - The user key for sending messages.
* @param {object} [opts.httpOptions] - Optional HTTP options.
* @param {boolean} [opts.debug] - Enable debug logging.
* @param {function} [opts.onerror] - Custom error handler.
* @param {boolean} [opts.update_sounds] - Automatically update sounds.
*/
declare function Pushover(opts: {
token: string;
user: string;
httpOptions?: object;
debug?: boolean;
onerror?: Function;
update_sounds?: boolean;
}): void;
declare class Pushover {
/**
* Creates a new Pushover instance.
* @class
* @param {object} opts - The options for Pushover.
* @param {string} opts.token - The Pushover API token.
* @param {string} opts.user - The user key for sending messages.
* @param {object} [opts.httpOptions] - Optional HTTP options.
* @param {boolean} [opts.debug] - Enable debug logging.
* @param {function} [opts.onerror] - Custom error handler.
* @param {boolean} [opts.update_sounds] - Automatically update sounds.
*/
constructor(opts: {
token: string;
user: string;
httpOptions?: object;
debug?: boolean;
onerror?: Function;
update_sounds?: boolean;
});
boundary: string;
token: string;
user: string;
httpOptions: any;
sounds: {
pushover: string;
bike: string;
bugle: string;
cashregister: string;
classical: string;
cosmic: string;
falling: string;
gamelan: string;
incoming: string;
intermission: string;
magic: string;
mechanical: string;
pianobar: string;
siren: string;
spacealarm: string;
tugboat: string;
alien: string;
climb: string;
persistent: string;
echo: string;
updown: string;
none: string;
};
debug: true;
onerror: Function;
/**
* Handles errors from Pushover API responses.
* @param {string|object} d - The response data from the API.
* @param {object} res - The HTTP response object.
* @throws {Error} Throws an error if there are API errors and no error handler is provided.
*/
errors(d: string | object, res: object): void;
/**
* Updates the list of available Pushover sounds.
*/
updateSounds(): void;
/**
* Sends a message using Pushover.
* @param {Message} obj - The message to send.
* @param {PushoverCallback} fn - The callback function that handles the response.
*/
send(obj: Message, fn: PushoverCallback): void;
}
declare namespace Pushover {
export { PushoverCallback, Message };
}
/**
* A callback function that handles the result of the Pushover send operation.
*/
type PushoverCallback = (error: Error | null, result: any) => any;
type Message = {
/**
* - The message to send
*/
message: string;
/**
* - The API token.
*/
token?: string;
/**
* - The user key.
*/
user?: string;
/**
* - A file path or binary image attachment to send with the message
*/
file?: string | object;
/**
* - The name of one of your devices to send just to that device instead of all devices
*/
device?: string;
/**
* - Set to 1 to enable HTML parsing
*/
html?: string;
/**
* - A value of -2, -1, 0 (default), 1, or 2
*/
priority?: string;
/**
* - The name of a supported sound to override your default sound choice
*/
sound?: string;
/**
* - A Unix timestamp of a time to display instead of when our API received it
*/
timestamp?: string;
/**
* - Your message's title, otherwise your app's name is used
*/
title?: string;
/**
* - A number of seconds that the message will live, before being deleted automatically
*/
ttl?: string;
/**
* - A supplementary URL to show with your message
*/
url?: string;
/**
* - A title for the URL specified as the url parameter, otherwise just the URL is shown
*/
url_title?: string;
};