Skip to content

Commit

Permalink
Add the ability to create stanzas via tagged template literal
Browse files Browse the repository at this point in the history
  • Loading branch information
jcbrand committed Sep 28, 2023
1 parent a1a9e41 commit db3848d
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Type checking via TypeScript and JSDoc typing annotations
Types definitions are now generated and placed in `./dist/types/`.
* Remove the deprecated `matchBare` option for `Strophe.Handler`. Use `matchBareFromJid` instead.
* Add the ability to create stanzas via a tagged template literal (`stx`).

## Version 1.6.2 - (2023-06-23)

Expand Down
3 changes: 2 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

import Strophe from './core.js';
import { $build, $msg, $pres, $iq } from './builder.js';
import { stx } from './stanza.js';

globalThis.$build = $build;
globalThis.$iq = $iq;
globalThis.$msg = $msg;
globalThis.$pres = $pres;
globalThis.Strophe = Strophe;

export { $build, $iq, $msg, $pres, Strophe };
export { $build, $iq, $msg, $pres, Strophe, stx };
80 changes: 80 additions & 0 deletions src/stanza.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import Strophe from './core.js';

const PARSE_ERROR_NS = 'http://www.w3.org/1999/xhtml';

/**
* @param { string } string
* @param { boolean } [throwErrorIfInvalidNS]
* @return { Element }
*/
export function toStanza (string, throwErrorIfInvalidNS) {
const doc = Strophe.xmlHtmlNode(string);

if (doc.getElementsByTagNameNS(PARSE_ERROR_NS, 'parsererror').length) {
throw new Error(`Parser Error: ${string}`);
}

const node = doc.firstElementChild;

if (
['message', 'iq', 'presence'].includes(node.nodeName.toLowerCase()) &&
node.namespaceURI !== 'jabber:client' &&
node.namespaceURI !== 'jabber:server'
) {
const err_msg = `Invalid namespaceURI ${node.namespaceURI}`;
if (throwErrorIfInvalidNS) {
throw new Error(err_msg);
} else {
Strophe.log(Strophe.LogLevel.ERROR, err_msg);
}
}
return node;
}

/**
* A Stanza represents a XML element used in XMPP (commonly referred to as
* stanzas).
*/
class Stanza {

/**
* @param { string[] } strings
* @param { any[] } values
*/
constructor (strings, values) {
this.strings = strings;
this.values = values;
}

/**
* @return { string }
*/
toString () {
this.string = this.string ||
this.strings.reduce((acc, str) => {
const idx = this.strings.indexOf(str);
const value = this.values.length > idx ? this.values[idx].toString() : '';
return acc + str + value;
}, '');
return this.string;
}

/**
* @return { Element }
*/
tree () {
this.node = this.node ?? toStanza(this.toString(), true);
return this.node;
}
}

/**
* Tagged template literal function which generates {@link Stanza } objects
* @example stx`<presence type="${type}" xmlns="jabber:client"><show>${show}</show></presence>`
*
* @param { string[] } strings
* @param { ...any } values
*/
export function stx (strings, ...values) {
return new Stanza(strings, values);
}
3 changes: 2 additions & 1 deletion src/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ import { $iq } from './builder.js';
import { $msg } from './builder.js';
import { $pres } from './builder.js';
import Strophe from './core.js';
export { $build, $iq, $msg, $pres, Strophe };
import { stx } from './stanza.js';
export { $build, $iq, $msg, $pres, Strophe, stx };
//# sourceMappingURL=index.d.ts.map
39 changes: 39 additions & 0 deletions src/types/stanza.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* @param { string } string
* @param { boolean } [throwErrorIfInvalidNS]
* @return { Element }
*/
export function toStanza(string: string, throwErrorIfInvalidNS?: boolean): Element;
/**
* Tagged template literal function which generates {@link Stanza } objects
* @example stx`<presence type="${type}" xmlns="jabber:client"><show>${show}</show></presence>`
*
* @param { string[] } strings
* @param { ...any } values
*/
export function stx(strings: string[], ...values: any[]): Stanza;
/**
* A Stanza represents a XML element used in XMPP (commonly referred to as
* stanzas).
*/
declare class Stanza {
/**
* @param { string[] } strings
* @param { any[] } values
*/
constructor(strings: string[], values: any[]);
strings: string[];
values: any[];
/**
* @return { string }
*/
toString(): string;
string: any;
/**
* @return { Element }
*/
tree(): Element;
node: any;
}
export {};
//# sourceMappingURL=stanza.d.ts.map

0 comments on commit db3848d

Please sign in to comment.