Skip to content

Commit

Permalink
Refactor the pubsub plugin
Browse files Browse the repository at this point in the history
- Turn it into a folder
- Use the stx tagged template literal
  • Loading branch information
jcbrand committed Dec 19, 2024
1 parent a825314 commit 90074f9
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 97 deletions.
3 changes: 1 addition & 2 deletions src/headless/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ export { MAMPlaceholderMessage } from './plugins/mam/index.js';
// XEP-0045 Multi-user chat
export { MUCMessage, MUCMessages, MUC, MUCOccupant, MUCOccupants } from './plugins/muc/index.js';


import './plugins/ping/index.js'; // XEP-0199 XMPP Ping
import './plugins/pubsub.js'; // XEP-0060 Pubsub
import './plugins/pubsub/index.js'; // XEP-0060 Pubsub

// RFC-6121 Contacts Roster
export { RosterContact, RosterContacts, RosterFilter, Presence, Presences } from './plugins/roster/index.js';
Expand Down
4 changes: 2 additions & 2 deletions src/headless/plugins/bookmarks/collection.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
/**
* @typedef {import('../muc/muc.js').default} MUC
*/
import { Stanza } from 'strophe.js';
import { Collection } from '@converse/skeletor';
import { getOpenPromise } from '@converse/openpromise';
import '../../plugins/muc/index.js';
import Bookmark from './model.js';
import _converse from '../../shared/_converse.js';
import api from '../../shared/api/index.js';
import converse from '../../shared/api/public.js';
import log from '../../log.js';
import { initStorage } from '../../utils/storage.js';
import { parseStanzaForBookmarks } from './parsers.js';
import { Stanza } from 'strophe.js';
import '../../plugins/muc/index.js';

const { Strophe, sizzle, stx } = converse.env;

Check notice

Code scanning / CodeQL

Unused variable, import, function or class Note

Unused variable sizzle.

Expand Down
93 changes: 0 additions & 93 deletions src/headless/plugins/pubsub.js

This file was deleted.

86 changes: 86 additions & 0 deletions src/headless/plugins/pubsub/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* @copyright The Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
import converse from '../../shared/api/public.js';
import _converse from '../../shared/_converse.js';
import api from '../../shared/api/index.js';
import log from '../../log.js';

const { Strophe, stx } = converse.env;

export default {
/**
* @typedef {import('strophe.js').Builder} Builder
* @typedef {import('strophe.js').Stanza} Stanza
*
* The "pubsub" namespace groups methods relevant to PubSub
* @namespace _converse.api.pubsub
* @memberOf _converse.api
*/
pubsub: {
/**
* Publshes an item to a PubSub node
*
* @method _converse.api.pubsub.publish
* @param {string} jid The JID of the pubsub service where the node resides.
* @param {string} node The node being published to
* @param {Builder|Stanza} item The Strophe.Builder representation of the XML element being published
* @param {import('./types').PubSubConfigOptions} options The publisher options
* (see https://xmpp.org/extensions/xep-0060.html#publisher-publish-options)
* @param {boolean} strict_options Indicates whether the publisher
* options are a strict requirement or not. If they're NOT
* strict, then Converse will publish to the node even if
* the publish options precondition cannot be met.
*/
async publish(jid, node, item, options, strict_options = true) {
const bare_jid = _converse.session.get('bare_jid')

Check notice

Code scanning / CodeQL

Semicolon insertion Note

Avoid automated semicolon insertion (90% of all statements in
the enclosing function
have an explicit semicolon).
const entity_jid = jid || bare_jid;
const supports_publish_options = await api.disco.supports(
Strophe.NS.PUBSUB + '#publish-options',
entity_jid
);
if (!supports_publish_options) {
log.warn(
`api.pubsub.publish: ${entity_jid} does not support #publish-options, ` +
`so we didn't set them even though they were provided.`
);
}

const stanza = stx`
<iq xmlns="jabber:client" from="${bare_jid}" type="set" to="${entity_jid}">
<pubsub xmlns="${Strophe.NS.PUBSUB}"><publish node="${node}">${item}</publish></pubsub>
${
options && supports_publish_options
? stx`<publish-options>
<x xmlns="${Strophe.NS.XFORM}" type="submit">
<field var="FORM_TYPE" type="hidden">
<value>${Strophe.NS.PUBSUB}#publish-options</value>
</field>
${Object.entries(options).map((k, v) => stx`<field var="${k}"><value>${v}</value></field>`)}
</x></publish-options>`
: ''
}
</iq>`;

try {
await api.sendIQ(stanza);
} catch (iq) {
if (
iq instanceof Element &&
!strict_options &&
iq.querySelector(`precondition-not-met[xmlns="${Strophe.NS.PUBSUB_ERROR}"]`)
) {
// The publish-options precondition couldn't be
// met. We re-publish but without publish-options.
const el = stanza.tree();
el.querySelector('publish-options').outerHTML = '';
log.warn(`api.pubsub.publish: Republishing without publish options. ${el.outerHTML}`);
await api.sendIQ(el);
} else {
throw iq;
}
}
},
},
};
21 changes: 21 additions & 0 deletions src/headless/plugins/pubsub/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* @module converse-pubsub
* @copyright The Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
import _converse from '../../shared/_converse.js';
import converse from '../../shared/api/public.js';
import pubsub_api from './api.js';
import '../disco/index.js';

const { Strophe } = converse.env;

Strophe.addNamespace('PUBSUB_ERROR', Strophe.NS.PUBSUB + '#errors');

converse.plugins.add('converse-pubsub', {
dependencies: ['converse-disco'],

initialize() {
Object.assign(_converse.api, pubsub_api);
},
});
42 changes: 42 additions & 0 deletions src/headless/plugins/pubsub/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
export type PubSubConfigOptions = {
'pubsub#access_model': 'authorize' | 'open' | 'presence' | 'roster' | 'whitelist';
// Payload XSLT
'pubsub#dataform_xslt'?: string;
'pubsub#deliver_notifications': boolean;
// Whether to deliver payloads with event notifications
'pubsub#deliver_payloads': boolean;
// Time after which to automatically purge items. `max` for no specific limit other than a server imposed maximum.
'pubsub#item_expire': string;
// Max # of items to persist. `max` for no specific limit other than a server imposed maximum.
'pubsub#max_items': string;
// Max Payload size in bytes
'pubsub#max_payload_size': string;
'pubsub#notification_type': 'normal' | 'headline';
// Notify subscribers when the node configuration changes
'pubsub#notify_config': boolean;
// Notify subscribers when the node is deleted
'pubsub#notify_delete': boolean;
// Notify subscribers when items are removed from the node
'pubsub#notify_retract': boolean;
// <field var='pubsub#notify_sub' type='boolean'
'pubsub#notify_sub': boolean;
// <field var='pubsub#persist_items' type='boolean'
'pubsub#persist_items': boolean;
// Deliver event notifications only to available users
'pubsub#presence_based_delivery': boolean;
'pubsub#publish_model': 'publishers' | 'subscribers' | 'open';
// Purge all items when the relevant publisher goes offline?
'pubsub#purge_offline': boolean;
'pubsub#roster_groups_allowed': string[];
// When to send the last published item
// - Never
// - When a new subscription is processed
// - When a new subscription is processed and whenever a subscriber comes online
'pubsub#send_last_published_item': 'never' | 'on_sub' | 'on_sub_and_presence';
// Whether to allow subscriptions
'pubsub#subscribe': boolean;
// A friendly name for the node'/>
'pubsub#title': string;
// Specify the semantic type of payload data to be provided at this node.
'pubsub#type': string;
};
21 changes: 21 additions & 0 deletions src/headless/types/plugins/pubsub/api.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
declare namespace _default {
namespace pubsub {
/**
* Publshes an item to a PubSub node
*
* @method _converse.api.pubsub.publish
* @param {string} jid The JID of the pubsub service where the node resides.
* @param {string} node The node being published to
* @param {Builder|Stanza} item The Strophe.Builder representation of the XML element being published
* @param {import('./types').PubSubConfigOptions} options The publisher options
* (see https://xmpp.org/extensions/xep-0060.html#publisher-publish-options)
* @param {boolean} strict_options Indicates whether the publisher
* options are a strict requirement or not. If they're NOT
* strict, then Converse will publish to the node even if
* the publish options precondition cannot be met.
*/
function publish(jid: string, node: string, item: import("strophe.js").Builder | import("strophe.js").Stanza, options: import("./types").PubSubConfigOptions, strict_options?: boolean): Promise<void>;
}
}
export default _default;
//# sourceMappingURL=api.d.ts.map
2 changes: 2 additions & 0 deletions src/headless/types/plugins/pubsub/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=index.d.ts.map
24 changes: 24 additions & 0 deletions src/headless/types/plugins/pubsub/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export type PubSubConfigOptions = {
'pubsub#access_model': 'authorize' | 'open' | 'presence' | 'roster' | 'whitelist';
'pubsub#dataform_xslt'?: string;
'pubsub#deliver_notifications': boolean;
'pubsub#deliver_payloads': boolean;
'pubsub#item_expire': string;
'pubsub#max_items': string;
'pubsub#max_payload_size': string;
'pubsub#notification_type': 'normal' | 'headline';
'pubsub#notify_config': boolean;
'pubsub#notify_delete': boolean;
'pubsub#notify_retract': boolean;
'pubsub#notify_sub': boolean;
'pubsub#persist_items': boolean;
'pubsub#presence_based_delivery': boolean;
'pubsub#publish_model': 'publishers' | 'subscribers' | 'open';
'pubsub#purge_offline': boolean;
'pubsub#roster_groups_allowed': string[];
'pubsub#send_last_published_item': 'never' | 'on_sub' | 'on_sub_and_presence';
'pubsub#subscribe': boolean;
'pubsub#title': string;
'pubsub#type': string;
};
//# sourceMappingURL=types.d.ts.map

0 comments on commit 90074f9

Please sign in to comment.