mod_rest/jsonmap.lib.lua
author Kim Alvefur <zash@zash.se>
Sun, 07 Mar 2021 01:26:20 +0100
changeset 4503 8e644bf36627
parent 4477 3b50a9a75fb6
child 4504 34c0f760f34a
permissions -rw-r--r--
mod_rest: Change OOB namespace to the one used in messages Because of it's current popularity as companion to HTTP Upload this is probably more useful than the iq one.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
local array = require "util.array";
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
local jid = require "util.jid";
3827
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
     3
local json = require "util.json";
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     4
local st = require "util.stanza";
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
local xml = require "util.xml";
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
3926
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
     7
local field_mappings; -- in scope for "func" mappings
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
     8
field_mappings = {
3890
b64b08b7bf8e mod_rest: Ignore already handled top-level stanza attr fields
Kim Alvefur <zash@zash.se>
parents: 3889
diff changeset
     9
	-- top level stanza attributes
b64b08b7bf8e mod_rest: Ignore already handled top-level stanza attr fields
Kim Alvefur <zash@zash.se>
parents: 3889
diff changeset
    10
	-- needed here to mark them as known fields
b64b08b7bf8e mod_rest: Ignore already handled top-level stanza attr fields
Kim Alvefur <zash@zash.se>
parents: 3889
diff changeset
    11
	kind = "attr",
b64b08b7bf8e mod_rest: Ignore already handled top-level stanza attr fields
Kim Alvefur <zash@zash.se>
parents: 3889
diff changeset
    12
	type = "attr",
b64b08b7bf8e mod_rest: Ignore already handled top-level stanza attr fields
Kim Alvefur <zash@zash.se>
parents: 3889
diff changeset
    13
	to = "attr",
b64b08b7bf8e mod_rest: Ignore already handled top-level stanza attr fields
Kim Alvefur <zash@zash.se>
parents: 3889
diff changeset
    14
	from = "attr",
b64b08b7bf8e mod_rest: Ignore already handled top-level stanza attr fields
Kim Alvefur <zash@zash.se>
parents: 3889
diff changeset
    15
	id = "attr",
4039
270cd50852be mod_rest: Map xml:lang to/from JSON
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
    16
	lang = "attr",
3890
b64b08b7bf8e mod_rest: Ignore already handled top-level stanza attr fields
Kim Alvefur <zash@zash.se>
parents: 3889
diff changeset
    17
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    18
	-- basic message
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    19
	body = "text_tag",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    20
	subject = "text_tag",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    21
	thread = "text_tag",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    22
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    23
	-- basic presence
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    24
	show = "text_tag",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    25
	status = "text_tag",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    26
	priority = "text_tag",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    27
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
    28
	state = { type = "name", xmlns = "http://jabber.org/protocol/chatstates" },
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
    29
	nick = { type = "text_tag", xmlns = "http://jabber.org/protocol/nick", tagname = "nick" },
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
    30
	delay = { type = "attr", xmlns = "urn:xmpp:delay", tagname = "delay", attr = "stamp" },
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
    31
	replace = { type = "attr", xmlns = "urn:xmpp:message-correct:0", tagname = "replace", attr = "id" },
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    32
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    33
	-- XEP-0045 MUC
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    34
	-- TODO history, password, ???
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
    35
	join = { type = "bool_tag", xmlns = "http://jabber.org/protocol/muc", tagname = "x" },
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    36
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    37
	-- XEP-0071
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    38
	html = {
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
    39
		type = "func", xmlns = "http://jabber.org/protocol/xhtml-im", tagname = "html",
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
    40
		st2json = function (s) --> json string
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
    41
			return (tostring(s:get_child("body", "http://www.w3.org/1999/xhtml")):gsub(" xmlns='[^']*'", "", 1));
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    42
		end;
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
    43
		json2st = function (s) --> xml
3821
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
    44
			if type(s) == "string" then
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
    45
				return assert(xml.parse("<x:html xmlns:x='http://jabber.org/protocol/xhtml-im' xmlns='http://www.w3.org/1999/xhtml'>" .. s .. "</x:html>"));
3821
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
    46
			end
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    47
		end;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    48
	};
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    49
3859
0e1e900577c4 mod_rest: Improve some comments
Kim Alvefur <zash@zash.se>
parents: 3858
diff changeset
    50
	-- XEP-0199: XMPP Ping
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
    51
	ping = { type = "bool_tag", xmlns = "urn:xmpp:ping", tagname = "ping" },
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    52
3858
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    53
	-- XEP-0092: Software Version
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
    54
	version = { type = "func", xmlns = "jabber:iq:version", tagname = "query",
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
    55
		st2json = function (s)
3858
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    56
			return {
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    57
				name = s:get_child_text("name");
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    58
				version = s:get_child_text("version");
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    59
				os = s:get_child_text("os");
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    60
			}
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    61
		end,
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
    62
		json2st = function (s)
3858
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    63
			local v = st.stanza("query", { xmlns = "jabber:iq:version" });
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    64
			if type(s) == "table" then
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    65
				v:text_tag("name", s.name);
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    66
				v:text_tag("version", s.version);
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    67
				if s.os then
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    68
					v:text_tag("os", s.os);
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    69
				end
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    70
			end
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    71
			return v;
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    72
		end
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    73
	};
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
    74
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    75
	-- XEP-0030
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    76
	disco = {
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
    77
		type = "func", xmlns = "http://jabber.org/protocol/disco#info", tagname = "query",
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
    78
		st2json = function (s) --> array of features
4477
3b50a9a75fb6 mod_rest: Roundtrip disco and items when string or boolean is used
Kim Alvefur <zash@zash.se>
parents: 4376
diff changeset
    79
			if s.tags[1] == nil then
3b50a9a75fb6 mod_rest: Roundtrip disco and items when string or boolean is used
Kim Alvefur <zash@zash.se>
parents: 4376
diff changeset
    80
				return s.attr.node or true;
3b50a9a75fb6 mod_rest: Roundtrip disco and items when string or boolean is used
Kim Alvefur <zash@zash.se>
parents: 4376
diff changeset
    81
			end
3957
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
    82
			local identities, features, extensions = array(), array(), {};
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    83
			for tag in s:childtags() do
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    84
				if tag.name == "identity" and tag.attr.category and tag.attr.type then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    85
					identities:push({ category = tag.attr.category, type = tag.attr.type, name = tag.attr.name });
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    86
				elseif tag.name == "feature" and tag.attr.var then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    87
					features:push(tag.attr.var);
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    88
				end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    89
			end
3957
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
    90
			for form in s:childtags("x", "jabber:x:data") do
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
    91
				local jform = field_mappings.formdata.st2json(form);
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
    92
				local form_type = jform["FORM_TYPE"];
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
    93
				if jform then
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
    94
					jform["FORM_TYPE"] = nil;
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
    95
					extensions[form_type] = jform;
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
    96
				end
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
    97
			end
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
    98
			if next(extensions) == nil then extensions = nil; end
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
    99
			return { node = s.attr.node, identities = identities, features = features, extensions = extensions };
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   100
		end;
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   101
		json2st = function (s)
3864
9752a6f1b9f3 mod_rest: Avoid treating special json.null value as any other table
Kim Alvefur <zash@zash.se>
parents: 3863
diff changeset
   102
			if type(s) == "table" and s ~= json.null then
3863
da3a0f055526 mod_rest: Fix handling of 'node' attribute in disco#info
Kim Alvefur <zash@zash.se>
parents: 3860
diff changeset
   103
				local disco = st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#info", node = s.node });
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   104
				if s.identities then
3852
1b9834500123 mod_rest: Fix iteration over disco#info identities
Kim Alvefur <zash@zash.se>
parents: 3827
diff changeset
   105
					for _, identity in ipairs(s.identities) do
3854
8d13b9c9ba75 mod_rest: Fix disco#info identities data mapping
Kim Alvefur <zash@zash.se>
parents: 3853
diff changeset
   106
						disco:tag("identity", { category = identity.category, type = identity.type, name = identity.name }):up();
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   107
					end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   108
				end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   109
				if s.features then
3853
11c34e97fe1a mod_rest: Fix iteration over disco#info features
Kim Alvefur <zash@zash.se>
parents: 3852
diff changeset
   110
					for _, feature in ipairs(s.features) do
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   111
						disco:tag("feature", { var = feature }):up();
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   112
					end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   113
				end
3957
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   114
				if s.extensions then
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   115
					for form_type, extension in pairs(s.extensions) do
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   116
						extension["FORM_TYPE"] = form_type;
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   117
						disco:add_child(field_mappings.formdata.json2st(extension));
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   118
					end
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   119
				end
3863
da3a0f055526 mod_rest: Fix handling of 'node' attribute in disco#info
Kim Alvefur <zash@zash.se>
parents: 3860
diff changeset
   120
				return disco;
4477
3b50a9a75fb6 mod_rest: Roundtrip disco and items when string or boolean is used
Kim Alvefur <zash@zash.se>
parents: 4376
diff changeset
   121
			elseif type(s) == "string" then
3b50a9a75fb6 mod_rest: Roundtrip disco and items when string or boolean is used
Kim Alvefur <zash@zash.se>
parents: 4376
diff changeset
   122
				return st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#info", node = s });
3863
da3a0f055526 mod_rest: Fix handling of 'node' attribute in disco#info
Kim Alvefur <zash@zash.se>
parents: 3860
diff changeset
   123
			else
3874
3261a82884bb mod_rest: Fix missing return
Kim Alvefur <zash@zash.se>
parents: 3864
diff changeset
   124
				return st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#info", });
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   125
			end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   126
		end;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   127
	};
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   128
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   129
	items = {
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   130
		type = "func", xmlns = "http://jabber.org/protocol/disco#items", tagname = "query",
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   131
		st2json = function (s) --> array of features | map with node
4477
3b50a9a75fb6 mod_rest: Roundtrip disco and items when string or boolean is used
Kim Alvefur <zash@zash.se>
parents: 4376
diff changeset
   132
			if s.tags[1] == nil then
3b50a9a75fb6 mod_rest: Roundtrip disco and items when string or boolean is used
Kim Alvefur <zash@zash.se>
parents: 4376
diff changeset
   133
				return s.attr.node or true;
3879
93f71ab6cb00 mod_rest: Support passing 'node' attr in disco#items queries
Kim Alvefur <zash@zash.se>
parents: 3875
diff changeset
   134
			end
93f71ab6cb00 mod_rest: Support passing 'node' attr in disco#items queries
Kim Alvefur <zash@zash.se>
parents: 3875
diff changeset
   135
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   136
			local items = array();
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   137
			for item in s:childtags("item") do
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   138
				items:push({ jid = item.attr.jid, node = item.attr.node, name = item.attr.name });
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   139
			end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   140
			return items;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   141
		end;
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   142
		json2st = function (s)
3864
9752a6f1b9f3 mod_rest: Avoid treating special json.null value as any other table
Kim Alvefur <zash@zash.se>
parents: 3863
diff changeset
   143
			if type(s) == "table" and s ~= json.null then
3879
93f71ab6cb00 mod_rest: Support passing 'node' attr in disco#items queries
Kim Alvefur <zash@zash.se>
parents: 3875
diff changeset
   144
				local disco = st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#items", node = s.node });
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   145
				for _, item in ipairs(s) do
3856
66f96b98d219 mod_rest: Allow returning an array of JID strings as disco#items
Kim Alvefur <zash@zash.se>
parents: 3855
diff changeset
   146
					if type(item) == "string" then
66f96b98d219 mod_rest: Allow returning an array of JID strings as disco#items
Kim Alvefur <zash@zash.se>
parents: 3855
diff changeset
   147
						disco:tag("item", { jid = item });
66f96b98d219 mod_rest: Allow returning an array of JID strings as disco#items
Kim Alvefur <zash@zash.se>
parents: 3855
diff changeset
   148
					elseif type(item) == "table" then
66f96b98d219 mod_rest: Allow returning an array of JID strings as disco#items
Kim Alvefur <zash@zash.se>
parents: 3855
diff changeset
   149
						disco:tag("item", { jid = item.jid, node = item.node, name = item.name });
66f96b98d219 mod_rest: Allow returning an array of JID strings as disco#items
Kim Alvefur <zash@zash.se>
parents: 3855
diff changeset
   150
					end
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   151
				end
3879
93f71ab6cb00 mod_rest: Support passing 'node' attr in disco#items queries
Kim Alvefur <zash@zash.se>
parents: 3875
diff changeset
   152
				return disco;
4477
3b50a9a75fb6 mod_rest: Roundtrip disco and items when string or boolean is used
Kim Alvefur <zash@zash.se>
parents: 4376
diff changeset
   153
			elseif type(s) == "string" then
3b50a9a75fb6 mod_rest: Roundtrip disco and items when string or boolean is used
Kim Alvefur <zash@zash.se>
parents: 4376
diff changeset
   154
				return st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#items", node = s });
3879
93f71ab6cb00 mod_rest: Support passing 'node' attr in disco#items queries
Kim Alvefur <zash@zash.se>
parents: 3875
diff changeset
   155
			else
93f71ab6cb00 mod_rest: Support passing 'node' attr in disco#items queries
Kim Alvefur <zash@zash.se>
parents: 3875
diff changeset
   156
				return st.stanza("query", { xmlns = "http://jabber.org/protocol/disco#items", });
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   157
			end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   158
		end;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   159
	};
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   160
3881
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   161
	-- XEP-0050: Ad-Hoc Commands
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   162
	command = { type = "func", xmlns = "http://jabber.org/protocol/commands", tagname = "command",
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   163
		st2json = function (s)
3881
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   164
			local cmd = {
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   165
				action = s.attr.action,
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   166
				node = s.attr.node,
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   167
				sessionid = s.attr.sessionid,
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   168
				status = s.attr.status,
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   169
			};
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   170
			local actions = s:get_child("actions");
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   171
			local note = s:get_child("note");
3882
9a3dfe0bf9fd mod_rest: Add JSON mapping for dataform (XEP-0004)
Kim Alvefur <zash@zash.se>
parents: 3881
diff changeset
   172
			local form = s:get_child("x", "jabber:x:data");
3881
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   173
			if actions then
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   174
				cmd.actions = {
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   175
					execute = actions.attr.execute,
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   176
				};
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   177
				for action in actions:childtags() do
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   178
					cmd.actions[action.name] = true
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   179
				end
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   180
			elseif note then
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   181
				cmd.note = {
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   182
					type = note.attr.type;
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   183
					text = note:get_text();
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   184
				};
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   185
			end
3882
9a3dfe0bf9fd mod_rest: Add JSON mapping for dataform (XEP-0004)
Kim Alvefur <zash@zash.se>
parents: 3881
diff changeset
   186
			if form then
3926
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   187
				cmd.form = field_mappings.dataform.st2json(form);
3882
9a3dfe0bf9fd mod_rest: Add JSON mapping for dataform (XEP-0004)
Kim Alvefur <zash@zash.se>
parents: 3881
diff changeset
   188
			end
3881
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   189
			return cmd;
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   190
		end;
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   191
		json2st = function (s)
3881
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   192
			if type(s) == "table" and s ~= json.null then
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   193
				local cmd = st.stanza("command", {
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   194
					xmlns = "http://jabber.org/protocol/commands",
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   195
					action = s.action,
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   196
					node = s.node,
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   197
					sessionid = s.sessionid,
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   198
					status = s.status,
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   199
				});
3885
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   200
				if type(s.actions) == "table" then
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   201
					cmd:tag("actions", { execute = s.actions.execute });
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   202
					do
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   203
						if s.actions.next == true then
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   204
							cmd:tag("next"):up();
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   205
						end
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   206
						if s.actions.prev == true then
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   207
							cmd:tag("prev"):up();
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   208
						end
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   209
						if s.actions.complete == true then
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   210
							cmd:tag("complete"):up();
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   211
						end
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   212
					end
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   213
					cmd:up();
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   214
				elseif type(s.note) == "table" then
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   215
					cmd:text_tag("note", s.note.text, { type = s.note.type });
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   216
				end
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   217
				if s.form then
3926
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   218
					cmd:add_child(field_mappings.dataform.json2st(s.form));
3892
04ea96a0488d mod_rest: Allow passing form data in a more compact format
Kim Alvefur <zash@zash.se>
parents: 3890
diff changeset
   219
				elseif s.data then
3926
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   220
					cmd:add_child(field_mappings.formdata.json2st(s.data));
3885
5d7df207dc2b mod_rest: Add final pieces of XEP-0050 (actions, note, form)
Kim Alvefur <zash@zash.se>
parents: 3884
diff changeset
   221
				end
3881
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   222
				return cmd;
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   223
			elseif type(s) == "string" then -- assume node
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   224
				return st.stanza("command", { xmlns = "http://jabber.org/protocol/commands", node = s });
3881
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   225
			end
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   226
			-- else .. missing required attribute
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   227
		end;
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   228
	};
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   229
3859
0e1e900577c4 mod_rest: Improve some comments
Kim Alvefur <zash@zash.se>
parents: 3858
diff changeset
   230
	-- XEP-0066: Out of Band Data
4503
8e644bf36627 mod_rest: Change OOB namespace to the one used in messages
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
   231
	oob_url = { type = "func", xmlns = "jabber:x:oob", tagname = "query",
8e644bf36627 mod_rest: Change OOB namespace to the one used in messages
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
   232
		-- XXX namespace depends on whether it's in an iq or message stanza
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   233
		st2json = function (s)
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   234
			return s:get_child_text("url");
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   235
		end;
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   236
		json2st = function (s)
3821
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   237
			if type(s) == "string" then
4503
8e644bf36627 mod_rest: Change OOB namespace to the one used in messages
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
   238
				return st.stanza("query", { xmlns = "jabber:x:oob" }):text_tag("url", s);
3821
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   239
			end
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   240
		end;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   241
	};
3827
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   242
3911
d5ecb9b9cb3b mod_rest: Update with namespace and name of XEP-0432
Kim Alvefur <zash@zash.se>
parents: 3910
diff changeset
   243
	-- XEP-0432: Simple JSON Messaging
d5ecb9b9cb3b mod_rest: Update with namespace and name of XEP-0432
Kim Alvefur <zash@zash.se>
parents: 3910
diff changeset
   244
	payload = { type = "func", xmlns = "urn:xmpp:json-msg:0", tagname = "payload",
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   245
		st2json = function (s)
3827
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   246
			local rawjson = s:get_child_text("json", "urn:xmpp:json:0");
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   247
			if not rawjson then return nil, "missing-json-payload"; end
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   248
			local parsed, err = json.decode(rawjson);
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   249
			if not parsed then return nil, err; end
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   250
			return {
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   251
				datatype = s.attr.datatype;
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   252
				data = parsed;
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   253
			};
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   254
		end;
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   255
		json2st = function (s)
3827
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   256
			if type(s) == "table" then
3911
d5ecb9b9cb3b mod_rest: Update with namespace and name of XEP-0432
Kim Alvefur <zash@zash.se>
parents: 3910
diff changeset
   257
				return st.stanza("payload", { xmlns = "urn:xmpp:json-msg:0", datatype = s.datatype })
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   258
				:tag("json", { xmlns = "urn:xmpp:json:0" }):text(json.encode(s.data));
3827
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   259
			end;
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   260
		end
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   261
	};
31b1797a78e1 mod_rest: Add support for XEP-XXXX: User-defined Data Transfer
Kim Alvefur <zash@zash.se>
parents: 3826
diff changeset
   262
3893
59765d1bb6dc mod_rest: Support mapping XEP-0004 Data Forms directly
Kim Alvefur <zash@zash.se>
parents: 3892
diff changeset
   263
	-- XEP-0004: Data Forms
3926
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   264
	dataform = {
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   265
		-- Generic and complete dataforms mapping
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   266
		type = "func", xmlns = "jabber:x:data", tagname = "x",
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   267
		st2json = function (s)
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   268
			local fields = array();
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   269
			local form = {
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   270
				type = s.attr.type;
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   271
				title = s:get_child_text("title");
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   272
				instructions = s:get_child_text("instructions");
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   273
				fields = fields;
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   274
			};
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   275
			for field in s:childtags("field") do
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   276
				local i = {
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   277
					var = field.attr.var;
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   278
					type = field.attr.type;
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   279
					label = field.attr.label;
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   280
					desc = field:get_child_text("desc");
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   281
					required = field:get_child("required") and true or nil;
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   282
					value = field:get_child_text("value");
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   283
				};
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   284
				if field.attr.type == "jid-multi" or field.attr.type == "list-multi" or field.attr.type == "text-multi" then
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   285
					local value = array();
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   286
					for v in field:childtags("value") do
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   287
						value:push(v:get_text());
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   288
					end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   289
					if field.attr.type == "text-multi" then
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   290
						i.value = value:concat("\n");
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   291
					else
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   292
						i.value = value;
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   293
					end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   294
				end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   295
				if field.attr.type == "list-single" or field.attr.type == "list-multi" then
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   296
					local options = array();
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   297
					for o in field:childtags("option") do
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   298
						options:push({ label = o.attr.label, value = o:get_child_text("value") });
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   299
					end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   300
					i.options = options;
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   301
				end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   302
				fields:push(i);
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   303
			end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   304
			return form;
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   305
		end;
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   306
		json2st = function (x)
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   307
			if type(x) == "table" and x ~= json.null then
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   308
				local form = st.stanza("x", { xmlns = "jabber:x:data", type = x.type });
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   309
				if x.title then
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   310
					form:text_tag("title", x.title);
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   311
				end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   312
				if x.instructions then
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   313
					form:text_tag("instructions", x.instructions);
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   314
				end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   315
				if type(x.fields) == "table" then
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   316
					for _, f in ipairs(x.fields) do
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   317
						if type(f) == "table" then
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   318
							form:tag("field", { var = f.var, type = f.type, label = f.label });
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   319
							if f.desc then
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   320
								form:text_tag("desc", f.desc);
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   321
							end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   322
							if f.required == true then
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   323
								form:tag("required"):up();
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   324
							end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   325
							if type(f.value) == "string" then
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   326
								form:text_tag("value", f.value);
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   327
							elseif type(f.value) == "table" then
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   328
								for _, v in ipairs(f.value) do
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   329
									form:text_tag("value", v);
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   330
								end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   331
							end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   332
							if type(f.options) == "table" then
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   333
								for _, o in ipairs(f.value) do
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   334
									if type(o) == "table" then
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   335
										form:tag("option", { label = o.label });
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   336
										form:text_tag("value", o.value);
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   337
										form:up();
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   338
									end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   339
								end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   340
							end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   341
						end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   342
					end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   343
				end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   344
				return form;
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   345
			end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   346
		end;
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   347
	};
3893
59765d1bb6dc mod_rest: Support mapping XEP-0004 Data Forms directly
Kim Alvefur <zash@zash.se>
parents: 3892
diff changeset
   348
3926
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   349
	-- Simpler mapping of dataform from JSON map
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   350
	formdata = { type = "func", xmlns = "jabber:x:data", tagname = "",
3957
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   351
		st2json = function (s)
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   352
			local r = {};
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   353
			for field in s:childtags("field") do
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   354
				if field.attr.var then
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   355
					local values = array();
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   356
					for value in field:childtags("value") do
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   357
						values:push(value:get_text());
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   358
					end
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   359
					if field.attr.type == "list-single" or field.attr.type == "list-multi" then
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   360
						r[field.attr.var] = values;
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   361
					elseif field.attr.type == "text-multi" then
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   362
						r[field.attr.var] = values:concat("\n");
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   363
					elseif field.attr.type == "boolean" then
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   364
						r[field.attr.var] = values[1] == "1" or values[1] == "true";
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   365
					elseif field.attr.type then
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   366
						r[field.attr.var] = values[1] or json.null;
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   367
					else -- type is optional, no way to know if multiple or single value is expected
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   368
						r[field.attr.var] = values;
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   369
					end
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   370
				end
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   371
			end
2c6d5734ae04 mod_rest: Add JSON mapping of XEP-0128: Service Discovery Extensions
Kim Alvefur <zash@zash.se>
parents: 3936
diff changeset
   372
			return r;
3893
59765d1bb6dc mod_rest: Support mapping XEP-0004 Data Forms directly
Kim Alvefur <zash@zash.se>
parents: 3892
diff changeset
   373
		end,
3926
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   374
		json2st = function (s, t)
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   375
			local form = st.stanza("x", { xmlns = "jabber:x:data", type = t });
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   376
			for k, v in pairs(s) do
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   377
				form:tag("field", { var = k });
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   378
				if type(v) == "string" then
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   379
					form:text_tag("value", v);
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   380
				elseif type(v) == "table" then
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   381
					for _, v_ in ipairs(v) do
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   382
						form:text_tag("value", v_);
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   383
					end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   384
				end
3936
8b34222216f4 mod_rest: Fix encoding of simple dataforms
Kim Alvefur <zash@zash.se>
parents: 3927
diff changeset
   385
				form:up();
3926
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   386
			end
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   387
			return form;
ea59c9455f93 mod_rest: Move dataforms into structure for more logical code order
Kim Alvefur <zash@zash.se>
parents: 3916
diff changeset
   388
		end
3893
59765d1bb6dc mod_rest: Support mapping XEP-0004 Data Forms directly
Kim Alvefur <zash@zash.se>
parents: 3892
diff changeset
   389
	};
3927
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   390
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   391
	-- XEP-0039: Statistics Gathering
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   392
	stats = { type = "func", xmlns = "http://jabber.org/protocol/stats", tagname = "query",
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   393
		st2json = function (s)
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   394
			local o = array();
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   395
			for stat in s:childtags("stat") do
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   396
				o:push({
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   397
						name = stat.attr.name;
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   398
						unit = stat.attr.unit;
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   399
						value = stat.attr.value;
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   400
					});
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   401
			end
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   402
			return o;
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   403
		end;
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   404
		json2st = function (j)
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   405
			local stats = st.stanza("query", { xmlns = "http://jabber.org/protocol/stats" });
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   406
			if type(j) == "table" then
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   407
				for _, stat in ipairs(j) do
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   408
					stats:tag("stat", { name = stat.name, unit = stat.unit, value = stat.value }):up();
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   409
				end
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   410
			end
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   411
			return stats;
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   412
		end;
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   413
	};
3c3d216c6f6d mod_rest: Add JSON mapping of XEP-0039: Statistics Gathering
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
   414
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   415
};
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   416
4313
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   417
local byxmlname = {};
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   418
for k, spec in pairs(field_mappings) do
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   419
	if type(spec) == "table" then
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   420
		spec.key = k;
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   421
		if spec.xmlns and spec.tagname then
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   422
			byxmlname["{" .. spec.xmlns .. "}" .. spec.tagname] = spec;
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   423
		elseif spec.type == "name" then
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   424
			byxmlname["{" .. spec.xmlns .. "}"] = spec;
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   425
		end
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   426
	elseif type(spec) == "string" then
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   427
		byxmlname["{jabber:client}" .. k] = {key = k; type = spec};
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   428
	end
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   429
end
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   430
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   431
local implied_kinds = {
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   432
	disco = "iq",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   433
	items = "iq",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   434
	ping = "iq",
3858
25c34c9f755c mod_rest: Add mapping of XEP-0092: Software Version
Kim Alvefur <zash@zash.se>
parents: 3856
diff changeset
   435
	version = "iq",
3881
562b34050561 mod_rest: Add basic support for XEP-0050: Ad-Hoc commands (no forms)
Kim Alvefur <zash@zash.se>
parents: 3879
diff changeset
   436
	command = "iq",
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   437
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   438
	body = "message",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   439
	html = "message",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   440
	replace = "message",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   441
	state = "message",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   442
	subject = "message",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   443
	thread = "message",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   444
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   445
	join = "presence",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   446
	priority = "presence",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   447
	show = "presence",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   448
	status = "presence",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   449
}
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   450
4025
1925d63eec6b mod_rest/jsonmap: Derive stanza @type from certain payloads
Kim Alvefur <zash@zash.se>
parents: 3957
diff changeset
   451
local implied_types = {
1925d63eec6b mod_rest/jsonmap: Derive stanza @type from certain payloads
Kim Alvefur <zash@zash.se>
parents: 3957
diff changeset
   452
	command = "set",
1925d63eec6b mod_rest/jsonmap: Derive stanza @type from certain payloads
Kim Alvefur <zash@zash.se>
parents: 3957
diff changeset
   453
}
1925d63eec6b mod_rest/jsonmap: Derive stanza @type from certain payloads
Kim Alvefur <zash@zash.se>
parents: 3957
diff changeset
   454
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   455
local kind_by_type = {
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   456
	get = "iq", set = "iq", result = "iq",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   457
	normal = "message", chat = "message", headline = "message", groupchat = "message",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   458
	available = "presence", unavailable = "presence",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   459
	subscribe = "presence", unsubscribe = "presence",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   460
	subscribed = "presence", unsubscribed = "presence",
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   461
}
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   462
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   463
local function st2json(s)
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   464
	local t = {
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   465
		kind = s.name,
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   466
		type = s.attr.type,
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   467
		to = s.attr.to,
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   468
		from = s.attr.from,
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   469
		id = s.attr.id,
4039
270cd50852be mod_rest: Map xml:lang to/from JSON
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
   470
		lang = s.attr["xml:lang"],
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   471
	};
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   472
	if s.name == "presence" and not s.attr.type then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   473
		t.type = "available";
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   474
	end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   475
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   476
	if t.to then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   477
		t.to = jid.prep(t.to);
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   478
		if not t.to then return nil, "invalid-jid-to"; end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   479
	end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   480
	if t.from then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   481
		t.from = jid.prep(t.from);
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   482
		if not t.from then return nil, "invalid-jid-from"; end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   483
	end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   484
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   485
	if t.type == "error" then
3875
e5d08bb58155 mod_rest: Map the error@by attribute
Kim Alvefur <zash@zash.se>
parents: 3874
diff changeset
   486
		local error = s:get_child("error");
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   487
		local err_typ, err_condition, err_text = s:get_error();
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   488
		t.error = {
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   489
			type = err_typ,
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   490
			condition = err_condition,
3875
e5d08bb58155 mod_rest: Map the error@by attribute
Kim Alvefur <zash@zash.se>
parents: 3874
diff changeset
   491
			text = err_text,
4255
d33b480befcb mod_rest: Fix attempt at indexing nil if an error stanza is missing <error>
Kim Alvefur <zash@zash.se>
parents: 4039
diff changeset
   492
			by = error and error.attr.by or nil,
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   493
		};
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   494
		return t;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   495
	end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   496
4376
78de3c7acf58 mod_rest: Fix json-mapping stanzas with text or whitespace between tags
Kim Alvefur <zash@zash.se>
parents: 4313
diff changeset
   497
	for _, tag in ipairs(s.tags) do
4313
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   498
		local prefix = "{" .. (tag.attr.xmlns or "jabber:client") .. "}";
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   499
		local mapping = byxmlname[prefix .. tag.name];
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   500
		if not mapping then
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   501
			mapping = byxmlname[prefix];
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   502
		end
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   503
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   504
		if not mapping then -- luacheck: ignore 542
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   505
			-- pass
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   506
		elseif mapping.type == "text_tag" then
4313
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   507
			t[mapping.key] = tag:get_text();
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   508
		elseif mapping.type == "name" then
4313
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   509
			t[mapping.key] = tag.name;
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   510
		elseif mapping.type == "attr" then
4313
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   511
			t[mapping.key] = tag.attr[mapping.attr];
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   512
		elseif mapping.type == "bool_tag" then
4313
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   513
			t[mapping.key] = true;
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   514
		elseif mapping.type == "func" and mapping.st2json then
4313
e8b9228b5265 mod_rest: Optimize stanza to JSON mapping
Kim Alvefur <zash@zash.se>
parents: 4255
diff changeset
   515
			t[mapping.key] = mapping.st2json(tag);
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   516
		end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   517
	end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   518
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   519
	return t;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   520
end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   521
3821
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   522
local function str(s)
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   523
	if type(s) == "string" then
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   524
		return s;
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   525
	end
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   526
end
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   527
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   528
local function json2st(t)
3821
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   529
	if type(t) ~= "table" or not str(next(t)) then
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   530
		return nil, "invalid-json";
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   531
	end
4025
1925d63eec6b mod_rest/jsonmap: Derive stanza @type from certain payloads
Kim Alvefur <zash@zash.se>
parents: 3957
diff changeset
   532
	local t_type = str(t.type);
1925d63eec6b mod_rest/jsonmap: Derive stanza @type from certain payloads
Kim Alvefur <zash@zash.se>
parents: 3957
diff changeset
   533
	if t_type == nil then
1925d63eec6b mod_rest/jsonmap: Derive stanza @type from certain payloads
Kim Alvefur <zash@zash.se>
parents: 3957
diff changeset
   534
		for k, implied in pairs(implied_types) do
1925d63eec6b mod_rest/jsonmap: Derive stanza @type from certain payloads
Kim Alvefur <zash@zash.se>
parents: 3957
diff changeset
   535
			if t[k] then
1925d63eec6b mod_rest/jsonmap: Derive stanza @type from certain payloads
Kim Alvefur <zash@zash.se>
parents: 3957
diff changeset
   536
				t_type = implied;
1925d63eec6b mod_rest/jsonmap: Derive stanza @type from certain payloads
Kim Alvefur <zash@zash.se>
parents: 3957
diff changeset
   537
			end
1925d63eec6b mod_rest/jsonmap: Derive stanza @type from certain payloads
Kim Alvefur <zash@zash.se>
parents: 3957
diff changeset
   538
		end
1925d63eec6b mod_rest/jsonmap: Derive stanza @type from certain payloads
Kim Alvefur <zash@zash.se>
parents: 3957
diff changeset
   539
	end
1925d63eec6b mod_rest/jsonmap: Derive stanza @type from certain payloads
Kim Alvefur <zash@zash.se>
parents: 3957
diff changeset
   540
	local kind = str(t.kind) or kind_by_type[t_type];
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   541
	if not kind then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   542
		for k, implied in pairs(implied_kinds) do
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   543
			if t[k] then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   544
				kind = implied;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   545
				break
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   546
			end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   547
		end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   548
	end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   549
4025
1925d63eec6b mod_rest/jsonmap: Derive stanza @type from certain payloads
Kim Alvefur <zash@zash.se>
parents: 3957
diff changeset
   550
	if t_type == "available" then
1925d63eec6b mod_rest/jsonmap: Derive stanza @type from certain payloads
Kim Alvefur <zash@zash.se>
parents: 3957
diff changeset
   551
		t_type = nil;
1925d63eec6b mod_rest/jsonmap: Derive stanza @type from certain payloads
Kim Alvefur <zash@zash.se>
parents: 3957
diff changeset
   552
	end
1925d63eec6b mod_rest/jsonmap: Derive stanza @type from certain payloads
Kim Alvefur <zash@zash.se>
parents: 3957
diff changeset
   553
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   554
	local s = st.stanza(kind or "message", {
4025
1925d63eec6b mod_rest/jsonmap: Derive stanza @type from certain payloads
Kim Alvefur <zash@zash.se>
parents: 3957
diff changeset
   555
		type = t_type;
3821
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   556
		to = str(t.to) and jid.prep(t.to);
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   557
		from = str(t.to) and jid.prep(t.from);
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   558
		id = str(t.id),
4039
270cd50852be mod_rest: Map xml:lang to/from JSON
Kim Alvefur <zash@zash.se>
parents: 4025
diff changeset
   559
		["xml:lang"] = str(t.lang),
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   560
	});
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   561
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   562
	if t.to and not s.attr.to then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   563
		return nil, "invalid-jid-to";
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   564
	end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   565
	if t.from and not s.attr.from then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   566
		return nil, "invalid-jid-from";
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   567
	end
3823
1bab6f67eb5f mod_rest: Fix previous commit
Kim Alvefur <zash@zash.se>
parents: 3822
diff changeset
   568
	if kind == "iq" and not s.attr.type then
1bab6f67eb5f mod_rest: Fix previous commit
Kim Alvefur <zash@zash.se>
parents: 3822
diff changeset
   569
		s.attr.type = "get";
3822
a607c69d0804 mod_rest: Guess 'get' as default type for 'iq' stanzas in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3821
diff changeset
   570
	end
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   571
3821
937f8c463be6 mod_rest: Stricter type checks in JSON mapping
Kim Alvefur <zash@zash.se>
parents: 3817
diff changeset
   572
	if type(t.error) == "table" then
3875
e5d08bb58155 mod_rest: Map the error@by attribute
Kim Alvefur <zash@zash.se>
parents: 3874
diff changeset
   573
		return st.error_reply(st.reply(s), str(t.error.type), str(t.error.condition), str(t.error.text), str(t.error.by));
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   574
	elseif t.type == "error" then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   575
		s:text_tag("error", t.body, { code = t.error_code and tostring(t.error_code) });
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   576
		return s;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   577
	end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   578
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   579
	for k, v in pairs(t) do
3899
25a3ad36ef3e mod_rest: Rename loop variable for improved clarity
Kim Alvefur <zash@zash.se>
parents: 3898
diff changeset
   580
		local mapping = field_mappings[k];
25a3ad36ef3e mod_rest: Rename loop variable for improved clarity
Kim Alvefur <zash@zash.se>
parents: 3898
diff changeset
   581
		if mapping then
25a3ad36ef3e mod_rest: Rename loop variable for improved clarity
Kim Alvefur <zash@zash.se>
parents: 3898
diff changeset
   582
			if mapping == "text_tag" then
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   583
				s:text_tag(k, v);
3899
25a3ad36ef3e mod_rest: Rename loop variable for improved clarity
Kim Alvefur <zash@zash.se>
parents: 3898
diff changeset
   584
			elseif mapping == "attr" then -- luacheck: ignore 542
3890
b64b08b7bf8e mod_rest: Ignore already handled top-level stanza attr fields
Kim Alvefur <zash@zash.se>
parents: 3889
diff changeset
   585
				-- handled already
3900
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   586
			elseif mapping.type == "text_tag" then
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   587
				s:text_tag(mapping.tagname or k, v, mapping.xmlns and { xmlns = mapping.xmlns });
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   588
			elseif mapping.type == "name" then
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   589
				s:tag(v, { xmlns = mapping.xmlns }):up();
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   590
			elseif mapping.type == "attr" then
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   591
				s:tag(mapping.tagname or k, { xmlns = mapping.xmlns, [mapping.attr or k] = v }):up();
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   592
			elseif mapping.type == "bool_tag" then
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   593
				s:tag(mapping.tagname or k, { xmlns = mapping.xmlns }):up();
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   594
			elseif mapping.type == "func" and mapping.json2st then
987b203bb091 mod_rest: Restructure JSON / Stanza mapping definitions
Kim Alvefur <zash@zash.se>
parents: 3899
diff changeset
   595
				s:add_child(mapping.json2st(v)):up();
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   596
			end
3889
1ec45dbc7db5 mod_rest: Return an error for unknown fields in JSON input
Kim Alvefur <zash@zash.se>
parents: 3885
diff changeset
   597
		else
1ec45dbc7db5 mod_rest: Return an error for unknown fields in JSON input
Kim Alvefur <zash@zash.se>
parents: 3885
diff changeset
   598
			return nil, "unknown-field";
3817
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   599
		end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   600
	end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   601
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   602
	s:reset();
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   603
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   604
	return s;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   605
end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   606
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   607
return {
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   608
	st2json = st2json;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   609
	json2st = json2st;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   610
};