aboutsummaryrefslogtreecommitdiffstats
path: root/teal-src
diff options
context:
space:
mode:
Diffstat (limited to 'teal-src')
-rw-r--r--teal-src/README.md48
-rw-r--r--teal-src/module.d.tl15
-rw-r--r--teal-src/prosody/core/storagemanager.d.tl74
-rw-r--r--teal-src/prosody/core/usermanager.d.tl46
-rw-r--r--teal-src/prosody/net/http.d.tl86
-rw-r--r--teal-src/prosody/net/http/codes.d.tl2
-rw-r--r--teal-src/prosody/net/http/errors.d.tl22
-rw-r--r--teal-src/prosody/net/http/files.d.tl14
-rw-r--r--teal-src/prosody/net/http/parser.d.tl58
-rw-r--r--teal-src/prosody/net/http/server.d.tl6
-rw-r--r--teal-src/prosody/net/server.d.tl65
-rw-r--r--teal-src/prosody/plugins/mod_cron.tl (renamed from teal-src/plugins/mod_cron.tl)8
-rw-r--r--teal-src/prosody/plugins/muc/muc.lib.d.tl178
-rw-r--r--teal-src/prosody/util/array.d.tl9
-rw-r--r--teal-src/prosody/util/async.d.tl42
-rw-r--r--teal-src/prosody/util/bitcompat.d.tl8
-rw-r--r--teal-src/prosody/util/compat.d.tl (renamed from teal-src/util/compat.d.tl)0
-rw-r--r--teal-src/prosody/util/crand.d.tl (renamed from teal-src/util/crand.d.tl)0
-rw-r--r--teal-src/prosody/util/crypto.d.tl29
-rw-r--r--teal-src/prosody/util/dataforms.d.tl54
-rw-r--r--teal-src/prosody/util/datamapper.tl (renamed from teal-src/util/datamapper.tl)14
-rw-r--r--teal-src/prosody/util/datetime.d.tl9
-rw-r--r--teal-src/prosody/util/encodings.d.tl (renamed from teal-src/util/encodings.d.tl)0
-rw-r--r--teal-src/prosody/util/error.d.tl (renamed from teal-src/util/error.d.tl)16
-rw-r--r--teal-src/prosody/util/format.d.tl (renamed from teal-src/util/format.d.tl)0
-rw-r--r--teal-src/prosody/util/hashes.d.tl (renamed from teal-src/util/hashes.d.tl)8
-rw-r--r--teal-src/prosody/util/hex.d.tl (renamed from teal-src/util/hex.d.tl)2
-rw-r--r--teal-src/prosody/util/http.d.tl (renamed from teal-src/util/http.d.tl)0
-rw-r--r--teal-src/prosody/util/human/io.d.tl28
-rw-r--r--teal-src/prosody/util/human/units.d.tl (renamed from teal-src/util/human/units.d.tl)5
-rw-r--r--teal-src/prosody/util/id.d.tl (renamed from teal-src/util/id.d.tl)0
-rw-r--r--teal-src/prosody/util/interpolation.d.tl (renamed from teal-src/util/interpolation.d.tl)0
-rw-r--r--teal-src/prosody/util/ip.d.tl20
-rw-r--r--teal-src/prosody/util/jid.d.tl (renamed from teal-src/util/jid.d.tl)0
-rw-r--r--teal-src/prosody/util/json.d.tl (renamed from teal-src/util/json.d.tl)0
-rw-r--r--teal-src/prosody/util/jsonpointer.tl (renamed from teal-src/util/jsonpointer.tl)0
-rw-r--r--teal-src/prosody/util/jsonschema.tl (renamed from teal-src/util/jsonschema.tl)133
-rw-r--r--teal-src/prosody/util/jwt.d.tl38
-rw-r--r--teal-src/prosody/util/logger.d.tl18
-rw-r--r--teal-src/prosody/util/mathcompat.tl15
-rw-r--r--teal-src/prosody/util/net.d.tl (renamed from teal-src/util/net.d.tl)0
-rw-r--r--teal-src/prosody/util/poll.d.tl (renamed from teal-src/util/poll.d.tl)0
-rw-r--r--teal-src/prosody/util/pposix.d.tl (renamed from teal-src/util/pposix.d.tl)0
-rw-r--r--teal-src/prosody/util/promise.d.tl22
-rw-r--r--teal-src/prosody/util/queue.d.tl21
-rw-r--r--teal-src/prosody/util/random.d.tl (renamed from teal-src/util/random.d.tl)0
-rw-r--r--teal-src/prosody/util/ringbuffer.d.tl (renamed from teal-src/util/ringbuffer.d.tl)0
-rw-r--r--teal-src/prosody/util/roles.d.tl32
-rw-r--r--teal-src/prosody/util/serialization.d.tl33
-rw-r--r--teal-src/prosody/util/set.d.tl22
-rw-r--r--teal-src/prosody/util/signal.d.tl (renamed from teal-src/util/signal.d.tl)8
-rw-r--r--teal-src/prosody/util/smqueue.tl (renamed from teal-src/util/smqueue.tl)2
-rw-r--r--teal-src/prosody/util/stanza.d.tl (renamed from teal-src/util/stanza.d.tl)93
-rw-r--r--teal-src/prosody/util/strbitop.d.tl (renamed from teal-src/util/strbitop.d.tl)0
-rw-r--r--teal-src/prosody/util/struct.d.tl6
-rw-r--r--teal-src/prosody/util/table.d.tl (renamed from teal-src/util/table.d.tl)1
-rw-r--r--teal-src/prosody/util/termcolours.d.tl7
-rw-r--r--teal-src/prosody/util/time.d.tl (renamed from teal-src/util/time.d.tl)0
-rw-r--r--teal-src/prosody/util/timer.d.tl8
-rw-r--r--teal-src/prosody/util/uuid.d.tl (renamed from teal-src/util/uuid.d.tl)2
-rw-r--r--teal-src/prosody/util/xtemplate.tl (renamed from teal-src/util/xtemplate.tl)2
-rw-r--r--teal-src/util/dataforms.d.tl52
-rw-r--r--teal-src/util/datetime.d.tl11
63 files changed, 1269 insertions, 123 deletions
diff --git a/teal-src/README.md b/teal-src/README.md
new file mode 100644
index 00000000..e8c47035
--- /dev/null
+++ b/teal-src/README.md
@@ -0,0 +1,48 @@
+# Teal definitions and sources
+
+This directory contains files written in the
+[Teal](https://github.com/teal-language/tl) language, a typed dialect of
+Lua. There are two kinds of files, `.tl` Teal source code and `.d.tl`
+type definitions files for modules written in Lua. The later allows
+writing type-aware Teal using regular Lua or C code.
+
+## Setup
+
+The Teal compiler can be installed from LuaRocks using:
+
+```bash
+luarocks install tl
+```
+
+## Checking types
+
+```bash
+tl check teal-src/prosody/util/example.tl
+```
+
+Some editors and IDEs also have support, see [text editor
+support](https://github.com/teal-language/tl#text-editor-support)
+
+
+## Compiling to Lua
+
+`GNUmakefile` contains a rule for building Lua files from Teal sources.
+It also applies [LuaFormat](https://github.com/Koihik/LuaFormatter) to
+make the resulting code more readable, albeit this makes the line
+numbers no longer match the original Teal source. Sometimes minor
+`luacheck` issues remain, such as types being represented as unused
+tables, which can be removed.
+
+```bash
+sensible-editor teal-src/prosody/util/example.tl
+# Write some code, remember to run tl check
+make util/example.lua
+sensible-editor util/example.lua
+# Apply any minor tweaks that may be needed
+```
+
+## Files of note
+
+`module.d.tl`
+: Describes the module environment.
+
diff --git a/teal-src/module.d.tl b/teal-src/module.d.tl
index 67b2437c..312dc227 100644
--- a/teal-src/module.d.tl
+++ b/teal-src/module.d.tl
@@ -1,4 +1,4 @@
-local st = require"util.stanza"
+local st = require "prosody.util.stanza"
global record moduleapi
get_name : function (moduleapi) : string
@@ -62,7 +62,12 @@ global record moduleapi
send_iq : function (moduleapi, st.stanza_t, util_session, number)
broadcast : function (moduleapi, { string }, st.stanza_t, function)
type timer_callback = function (number, ... : any) : number
- add_timer : function (moduleapi, number, timer_callback, ... : any)
+ record timer_wrapper
+ stop : function (timer_wrapper)
+ disarm : function (timer_wrapper)
+ reschedule : function (timer_wrapper, number)
+ end
+ add_timer : function (moduleapi, number, timer_callback, ... : any) : timer_wrapper
get_directory : function (moduleapi) : string
enum file_mode
"r" "w" "a" "r+" "w+" "a+"
@@ -70,6 +75,7 @@ global record moduleapi
load_resource : function (moduleapi, string, file_mode) : FILE
enum store_type
"keyval"
+ "keyval+"
"map"
"archive"
end
@@ -121,6 +127,11 @@ global record moduleapi
path : string
resource_path : string
+ -- access control
+ may : function (moduleapi, string, table|string)
+ default_permission : function (string, string)
+ default_permissions : function (string, { string })
+
-- methods the module can add
load : function ()
add_host : function (moduleapi)
diff --git a/teal-src/prosody/core/storagemanager.d.tl b/teal-src/prosody/core/storagemanager.d.tl
new file mode 100644
index 00000000..bd82357c
--- /dev/null
+++ b/teal-src/prosody/core/storagemanager.d.tl
@@ -0,0 +1,74 @@
+-- Storage local record API Description
+--
+-- This is written as a TypedLua description
+
+-- Key-Value stores (the default)
+
+local stanza = require"prosody.util.stanza".stanza_t
+
+local record keyval_store
+ get : function ( keyval_store, string ) : any , string
+ set : function ( keyval_store, string, any ) : boolean, string
+end
+
+-- Map stores (key-key-value stores)
+
+local record map_store
+ get : function ( map_store, string, any ) : any, string
+ set : function ( map_store, string, any, any ) : boolean, string
+ set_keys : function ( map_store, string, { any : any }) : boolean, string
+ remove : table
+end
+
+-- Archive stores
+
+local record archive_query
+ start : number -- timestamp
+ ["end"]: number -- timestamp
+ with : string
+ after : string -- archive id
+ before : string -- archive id
+ total : boolean
+end
+
+local record archive_store
+ -- Optional set of capabilities
+ caps : {
+ -- Optional total count of matching items returned as second return value from :find()
+ string : any
+ }
+
+ -- Add to the archive
+ append : function ( archive_store, string, string, any, number, string ) : string, string
+
+ -- Iterate over archive
+ type iterator = function () : string, any, number, string
+ find : function ( archive_store, string, archive_query ) : iterator, integer
+
+ -- Removal of items. API like find. Optional
+ delete : function ( archive_store, string, archive_query ) : boolean | number, string
+
+ -- Array of dates which do have messages (Optional)
+ dates : function ( archive_store, string ) : { string }, string
+
+ -- Map of counts per "with" field
+ summary : function ( archive_store, string, archive_query ) : { string : integer }, string
+
+ -- Map-store API
+ get : function ( archive_store, string, string ) : stanza, number, string
+ get : function ( archive_store, string, string ) : nil, string
+ set : function ( archive_store, string, string, stanza, number, string ) : boolean, string
+end
+
+-- This represents moduleapi
+local record coremodule
+ -- If the first string is omitted then the name of the module is used
+ -- The second string is one of "keyval" (default), "map" or "archive"
+ open_store : function (archive_store, string, string) : keyval_store, string
+ open_store : function (archive_store, string, string) : map_store, string
+ open_store : function (archive_store, string, string) : archive_store, string
+
+ -- Other module methods omitted
+end
+
+return coremodule
diff --git a/teal-src/prosody/core/usermanager.d.tl b/teal-src/prosody/core/usermanager.d.tl
new file mode 100644
index 00000000..fc055004
--- /dev/null
+++ b/teal-src/prosody/core/usermanager.d.tl
@@ -0,0 +1,46 @@
+local Role = require "prosody.util.roles".Role;
+
+local record usermanager
+ record AuthProvider
+ -- TODO
+ end
+ record AccountInfo
+ created : number
+ password_updated : any
+ enabled : boolean
+ end
+
+ -- Users
+ test_password : function (username : string, host : string, password : string) : boolean
+ get_password : function (username : string, host : string) : string, string
+ set_password : function (username : string, host : string, password : string) : boolean, string
+ get_account_info : function (username : string, host : string) : AccountInfo
+ user_exists : function (username : string, host : string) : boolean
+ create_user : function (username : string, password : string, host : string) : boolean, string
+ delete_user : function (username : string, host : string) : boolean, string
+ user_is_enabled : function (username : string, host : string) : boolean, string
+ enable_user : function (username : string, host : string) : boolean, string
+ disable_user : function (username : string, host : string) : boolean, string
+ users : function (host : string) : function () : string
+
+ -- Roles
+ get_user_role : function (username : string, host : string) : Role
+ set_user_role : function (username : string, host : string, role_name : string) : boolean, string
+ user_can_assume_role : function (username : string, host : string, role_name : string) : boolean
+ add_user_secondary_role : function (username : string, host: string, role_name : string) : boolean, string
+ remove_user_secondary_role : function (username : string, host: string, role_name : string) : boolean, string
+ get_user_secondary_roles : function (username : string, host : string) : { string : Role }
+ get_users_with_role : function (role : string, host : string) : { string }
+ get_jid_role : function (jid : string, host : string) : Role
+ set_jid_role : function (jid : string, host : string, role_name : string) : boolean
+ get_jids_with_role : function (role : string, host : string) : { string }
+ get_role_by_name : function (role_name : string) : Role
+
+ -- Etc
+ get_provider : function (host : string) : AuthProvider
+ get_sasl_handler : function (host : string, session : table) : table
+ initialize_host : function (host : string)
+ new_null_provider : function () : AuthProvider
+end
+
+return usermanager
diff --git a/teal-src/prosody/net/http.d.tl b/teal-src/prosody/net/http.d.tl
new file mode 100644
index 00000000..43b0bf4d
--- /dev/null
+++ b/teal-src/prosody/net/http.d.tl
@@ -0,0 +1,86 @@
+local Promise = require "prosody.util.promise".Promise;
+
+local record sslctx -- from LuaSec
+end
+
+local record lib
+
+ enum http_method
+ "GET"
+ "HEAD"
+ "POST"
+ "PUT"
+ "OPTIONS"
+ "DELETE"
+ -- etc?
+ end
+
+ record http_client_options
+ sslctx : sslctx
+ end
+
+ record http_options
+ id : string
+ onlystatus : boolean
+ body : string
+ method : http_method
+ headers : { string : string }
+ insecure : boolean
+ suppress_errors : boolean
+ streaming_handler : function
+ suppress_url : boolean
+ sslctx : sslctx
+ end
+
+ record http_request
+ host : string
+ port : string
+ enum Scheme
+ "http"
+ "https"
+ end
+ scheme : Scheme
+ url : string
+ userinfo : string
+ path : string
+
+ method : http_method
+ headers : { string : string }
+
+ insecure : boolean
+ suppress_errors : boolean
+ streaming_handler : function
+ http : http_client
+ time : integer
+ id : string
+ callback : http_callback
+ end
+
+ record http_response
+ end
+
+ type http_callback = function (string, number, http_response, http_request)
+
+ record http_client
+ options : http_client_options
+ request : function (http_client, string, http_options, http_callback)
+ end
+
+ request : function (string, http_options, http_callback) : Promise, string
+ default : http_client
+ new : function (http_client_options) : http_client
+ events : table
+ -- COMPAT
+ urlencode : function (string) : string
+ urldecode : function (string) : string
+ formencode : function ({ string : string }) : string
+ formdecode : function (string) : { string : string }
+ destroy_request : function (http_request)
+
+ enum available_features
+ "sni"
+ end
+ features : { available_features : boolean }
+end
+
+return lib
diff --git a/teal-src/prosody/net/http/codes.d.tl b/teal-src/prosody/net/http/codes.d.tl
new file mode 100644
index 00000000..65d004fc
--- /dev/null
+++ b/teal-src/prosody/net/http/codes.d.tl
@@ -0,0 +1,2 @@
+local type response_codes = { integer : string }
+return response_codes
diff --git a/teal-src/prosody/net/http/errors.d.tl b/teal-src/prosody/net/http/errors.d.tl
new file mode 100644
index 00000000..a9b6ea6c
--- /dev/null
+++ b/teal-src/prosody/net/http/errors.d.tl
@@ -0,0 +1,22 @@
+local record http_errors
+ enum known_conditions
+ "cancelled"
+ "connection-closed"
+ "certificate-chain-invalid"
+ "certificate-verify-failed"
+ "connection failed"
+ "invalid-url"
+ "unable to resolve service"
+ end
+ type registry_keys = known_conditions | integer
+ record error
+ type : string
+ condition : string
+ code : integer
+ text : string
+ end
+ registry : { registry_keys : error }
+ new : function (integer, known_conditions, table)
+ new : function (integer, string, table)
+end
+return http_errors
diff --git a/teal-src/prosody/net/http/files.d.tl b/teal-src/prosody/net/http/files.d.tl
new file mode 100644
index 00000000..d0ba5c1c
--- /dev/null
+++ b/teal-src/prosody/net/http/files.d.tl
@@ -0,0 +1,14 @@
+local record serve_options
+ path : string
+ mime_map : { string : string }
+ cache_size : integer
+ cache_max_file_size : integer
+ index_files : { string }
+ directory_index : boolean
+end
+
+local record http_files
+ serve : function(serve_options|string) : function
+end
+
+return http_files
diff --git a/teal-src/prosody/net/http/parser.d.tl b/teal-src/prosody/net/http/parser.d.tl
new file mode 100644
index 00000000..1cd6ccf4
--- /dev/null
+++ b/teal-src/prosody/net/http/parser.d.tl
@@ -0,0 +1,58 @@
+local record httpstream
+ feed : function(httpstream, string)
+end
+
+local type sink_cb = function ()
+
+local record httppacket
+ enum http_method
+ "HEAD"
+ "GET"
+ "POST"
+ "PUT"
+ "DELETE"
+ "OPTIONS"
+ -- etc
+ end
+ method : http_method
+ record url_details
+ path : string
+ query : string
+ end
+ url : url_details
+ path : string
+ enum http_version
+ "1.0"
+ "1.1"
+ end
+ httpversion : http_version
+ headers : { string : string }
+ body : string | boolean
+ body_sink : sink_cb
+ chunked : boolean
+ partial : boolean
+end
+
+local enum error_conditions
+ "cancelled"
+ "connection-closed"
+ "certificate-chain-invalid"
+ "certificate-verify-failed"
+ "connection failed"
+ "invalid-url"
+ "unable to resolve service"
+end
+
+local type success_cb = function (httppacket)
+local type error_cb = function (error_conditions)
+
+local enum stream_mode
+ "client"
+ "server"
+end
+
+local record lib
+ new : function (success_cb, error_cb, stream_mode) : httpstream
+end
+
+return lib
diff --git a/teal-src/prosody/net/http/server.d.tl b/teal-src/prosody/net/http/server.d.tl
new file mode 100644
index 00000000..5a83af7e
--- /dev/null
+++ b/teal-src/prosody/net/http/server.d.tl
@@ -0,0 +1,6 @@
+
+local record http_server
+ -- TODO
+end
+
+return http_server
diff --git a/teal-src/prosody/net/server.d.tl b/teal-src/prosody/net/server.d.tl
new file mode 100644
index 00000000..bb61f677
--- /dev/null
+++ b/teal-src/prosody/net/server.d.tl
@@ -0,0 +1,65 @@
+local record server
+ record LuaSocketTCP
+ end
+ record LuaSecCTX
+ end
+
+ record extra_settings
+ end
+
+ record interface
+ end
+ enum socket_type
+ "tcp"
+ "tcp6"
+ "tcp4"
+ end
+
+ record listeners
+ onconnect : function (interface)
+ ondetach : function (interface)
+ onattach : function (interface, string)
+ onincoming : function (interface, string, string)
+ ondrain : function (interface)
+ onreadtimeout : function (interface)
+ onstarttls : function (interface)
+ onstatus : function (interface, string)
+ ondisconnect : function (interface, string)
+ end
+
+ get_backend : function () : string
+
+ type port = string | integer
+ enum read_mode
+ "*a"
+ "*l"
+ end
+ type read_size = read_mode | integer
+ addserver : function (string, port, listeners, read_size, LuaSecCTX) : interface
+ addclient : function (string, port, listeners, read_size, LuaSecCTX, socket_type, extra_settings) : interface
+ record listen_config
+ read_size : read_size
+ tls_ctx : LuaSecCTX
+ tls_direct : boolean
+ sni_hosts : { string : LuaSecCTX }
+ end
+ listen : function (string, port, listeners, listen_config) : interface
+ enum quitting
+ "quitting"
+ end
+ loop : function () : quitting
+ closeall : function ()
+ setquitting : function (boolean | quitting)
+
+ wrapclient : function (LuaSocketTCP, string, port, listeners, read_size, LuaSecCTX, extra_settings) : interface
+ wrapserver : function (LuaSocketTCP, string, port, listeners, listen_config) : interface
+ watchfd : function (integer | LuaSocketTCP, function (interface), function (interface)) : interface
+ link : function ()
+
+ record config
+ end
+ set_config : function (config)
+
+end
+
+return server
diff --git a/teal-src/plugins/mod_cron.tl b/teal-src/prosody/plugins/mod_cron.tl
index f3b8f62f..b71b5f74 100644
--- a/teal-src/plugins/mod_cron.tl
+++ b/teal-src/prosody/plugins/mod_cron.tl
@@ -1,7 +1,7 @@
module:set_global();
-local async = require "util.async";
-local datetime = require "util.datetime";
+local async = require "prosody.util.async";
+local datetime = require "prosody.util.datetime";
local record map_store<K,V>
-- TODO move to somewhere sensible
@@ -88,8 +88,8 @@ local function run_task(task : task_spec)
task:save(started_at);
end
-local task_runner = async.runner(run_task);
-module:add_timer(1, function() : integer
+local task_runner : async.runner_t<task_spec> = async.runner(run_task);
+scheduled = module:add_timer(1, function() : integer
module:log("info", "Running periodic tasks");
local delay = 3600;
for host in pairs(active_hosts) do
diff --git a/teal-src/prosody/plugins/muc/muc.lib.d.tl b/teal-src/prosody/plugins/muc/muc.lib.d.tl
new file mode 100644
index 00000000..6e9663a1
--- /dev/null
+++ b/teal-src/prosody/plugins/muc/muc.lib.d.tl
@@ -0,0 +1,178 @@
+local Stanza = require "prosody.util.stanza".stanza_t
+
+local record Room
+ jid : string
+
+ enum Affiliation
+ "outcast"
+ "none"
+ "member"
+ "admin"
+ "owner"
+ end
+
+ enum Role
+ "none"
+ "visitor"
+ "participant"
+ "moderator"
+ end
+
+ record Occupant
+ bare_jid : string
+ nick : string
+ sessions : { string : Stanza }
+ role : Role
+ jid : string
+
+ choose_new_primary : function (Occupant) : string
+ set_session : function (Occupant, string, Stanza, boolean)
+ remove_session : function (Occupant, string)
+ each_session : function (Occupant) -- TODO Iterator
+
+ end
+
+ -- Private properties
+ _jid_nick : { string : string }
+ _occupants : { string : Occupant }
+ _data : { string : any }
+ _affiliations : { string : Affiliation }
+ _affiliation_data : { string : { string : any } }
+
+ -- Occupant methods
+ get_occupant_jid : function (Room, real_jid : string) : string
+ new_occupant : function (Room, bare_real_jid : string, nick : string) : Occupant
+ get_occupant_by_nick : function (Room, nick : string) : Occupant
+ type OccupantIterator = function ({string:Occupant}, occupant_jid : string) : string, Occupant
+ each_occupant : function (Room, read_only : boolean) : OccupantIterator, {string:Occupant}, nil
+ has_occupant : function (Room) : boolean
+ get_occupant_by_real_jid : function (Room, real_jid : string) : Occupant
+ save_occupant :function (Room, Occupant) : Occupant
+
+ -- Affiliation methods
+ type AffiliationIterator = function (any, jid : string) : string, Affiliation
+ get_affiliation : function (Room, jid : string) : Affiliation
+ each_affiliation : function (Room, Affiliation) : AffiliationIterator, nil, nil
+ set_affiliation : function (Room, jid : string, Affiliation, reason : string, data : { string : any }) : boolean, string, string, string -- ok + error tripplet
+ get_affiliation_data : function (Room, jid : string, key : string) : any
+ set_affiliation_data : function (Room, jid : string, key : string, value : any) : boolean
+ get_registered_nick : function (Room, jid : string) : string
+ get_registered_jid : function (Room, nick : string) : string
+
+ -- Role methods
+ get_default_role : function (Room, Affiliation) : Role, integer
+ get_role : function (Room, nick : string) : Role
+ may_set_role : function (Room, actor : string, Occupant, Role) : boolean
+ set_role : function (Room, actor : string, occupant_jid : string, Role, reason : string) : boolean, string, string, string
+
+ -- Routing input, generally handled by mod_muc and hooked up to Prosody routing events
+ handle_first_presence : function (Room, table, Stanza) : boolean
+ handle_normal_presence : function (Room, table, Stanza) : boolean
+ handle_presence_to_room : function (Room, table, Stanza) : boolean
+ handle_presence_to_occupant : function (Room, table, Stanza) : boolean
+ handle_message_to_room : function (Room, table, Stanza) : boolean
+ handle_message_to_occupant : function (Room, table, Stanza) : boolean
+ handle_groupchat_to_room : function (Room, table, Stanza) : boolean
+ handle_iq_to_occupant : function (Room, table, Stanza) : boolean
+ handle_disco_info_get_query : function (Room, table, Stanza) : boolean
+ handle_disco_items_get_query : function (Room, table, Stanza) : boolean
+ handle_admin_query_set_command : function (Room, table, Stanza) : boolean
+ handle_admin_query_get_command : function (Room, table, Stanza) : boolean
+ handle_owner_query_get_to_room : function (Room, table, Stanza) : boolean
+ handle_owner_query_set_to_room : function (Room, table, Stanza) : boolean
+ handle_mediated_invite : function (Room, table, Stanza) : boolean
+ handle_mediated_decline : function (Room, table, Stanza) : boolean
+ handle_role_request : function (Room, table, Stanza) : boolean
+ handle_register_iq : function (Room, table, Stanza) : boolean
+ handle_kickable : function (Room, table, Stanza) : boolean
+
+ -- Routing output
+ broadcast : function (Room, Stanza, function (nick : string, Occupant) : boolean)
+ broadcast_message : function (Room, Stanza) : boolean
+ route_stanza : function (Room, Stanza)
+ route_to_occupant : function (Room, Occupant, Stanza)
+
+ -- Sending things to someone joining
+ publicise_occupant_status : function (Room, Occupant, x : Stanza, nick : string, actor : string, reason : string, prev_role : Role, force_unavailable : boolean, recipient : Occupant)
+ send_occupant_list : function (Room, to : string, filter : function (occupant_jid : string, Occupant) : boolean)
+ send_history : function (Room, Stanza)
+ send_subject : function (Room, to : string, time : number)
+
+ respond_to_probe : function (Room, table, Stanza, Occupant)
+
+ -- Constructors for various answer stanzas
+ get_disco_info : function (Room, Stanza) : Stanza
+ get_disco_items : function (Room, Stanza) : Stanza
+
+ build_item_list : function (Room, Occupant, Stanza, is_anonymous : boolean, nick : string, actor_nick : string, actor_jid : string, reason : string) : Stanza
+ build_unavailable_presence : function (Room, from_muc_jid : string, to_jid : string) : Stanza
+
+ -- Form handling
+ send_form : function (Room, table, Stanza)
+ get_form_layout : function (Room, actor : string) : table
+ process_form : function (Room, table, Stanza) : boolean
+
+ -- Properties and configuration
+ get_name : function (Room) : string
+ set_name : function (Room, string) : boolean
+ get_description : function (Room) : string
+ set_description : function (Room, string) : boolean
+ get_language : function (Room) : string
+ set_language : function (Room, string) : boolean
+ get_hidden : function (Room) : boolean
+ set_hidden : function (Room, boolean)
+ get_public : function (Room) : boolean
+ set_public : function (Room, boolean)
+ get_password : function (Room) : string
+ set_password : function (Room, string) : boolean
+ get_members_only : function (Room) : boolean
+ set_members_only : function (Room, boolean) : boolean
+ get_allow_member_invites : function (Room) : boolean
+ set_allow_member_invites : function (Room, boolean) : boolean
+ get_moderated : function (Room) : boolean
+ set_moderated : function (Room, boolean) : boolean
+ get_persistent : function (Room) : boolean
+ set_persistent : function (Room, boolean) : boolean
+ get_changesubject : function (Room) : boolean
+ set_changesubject : function (Room, boolean) : boolean
+ get_subject : function (Room) : string
+ set_subject : function (Room, string) : boolean
+ get_historylength : function (Room) : integer
+ set_historylength : function (Room, integer) : boolean
+ get_presence_broadcast : function (Room) : { Role : boolean }
+ set_presence_broadcast : function (Room, { Role : boolean }) : boolean
+
+ is_anonymous_for : function (Room, jid : string) : boolean
+ get_salt : function (Room) : string
+ get_occupant_id : function (Room, Occupant)
+
+ -- Room teardown
+ clear : function (Room, x : Stanza)
+ destroy : function (Room, newjid : string, reason : string, password : string) : boolean
+
+ -- Room state persistence
+ record FrozenRoom
+ _jid : string
+ _data : { string : any }
+ _affiliation_data : { string : { string : any } }
+ -- { string : Affiliation }
+ end
+
+ record StateEntry
+ bare_jid : string
+ role : Role
+ jid : string
+ end
+
+ save : function (Room, forced : boolean, savestate : boolean) : boolean
+ freeze : function (Room, live : boolean) : FrozenRoom, { string : StateEntry }
+end
+
+local record lib
+ new_room : function (jid : string, config : { string : any }) : Room
+ restore_room : function (Room.FrozenRoom, { string : Room.StateEntry }) : Room
+
+ room_mt : metatable
+end
+
+return lib
diff --git a/teal-src/prosody/util/array.d.tl b/teal-src/prosody/util/array.d.tl
new file mode 100644
index 00000000..70bf2624
--- /dev/null
+++ b/teal-src/prosody/util/array.d.tl
@@ -0,0 +1,9 @@
+local record array_t<T>
+ { T }
+end
+
+local record lib
+ metamethod __call : function () : array_t
+end
+
+return lib
diff --git a/teal-src/prosody/util/async.d.tl b/teal-src/prosody/util/async.d.tl
new file mode 100644
index 00000000..a2e41cd6
--- /dev/null
+++ b/teal-src/prosody/util/async.d.tl
@@ -0,0 +1,42 @@
+local record lib
+ ready : function () : boolean
+ waiter : function (num : integer, allow_many : boolean) : function (), function ()
+ guarder : function () : function (id : function ()) : function () | nil
+ record runner_t<T>
+ func : function (T)
+ thread : thread
+ enum state_e
+ -- from Lua manual
+ "running"
+ "suspended"
+ "normal"
+ "dead"
+
+ -- from util.async
+ "ready"
+ "error"
+ end
+ state : state_e
+ notified_state : state_e
+ queue : { T }
+ type watcher_t = function (runner_t<T>, ... : any)
+ type watchers_t = { state_e : watcher_t }
+ data : any
+ id : string
+
+ run : function (runner_t<T>, T) : boolean, state_e, integer
+ enqueue : function (runner_t<T>, T) : runner_t<T>
+ log : function (runner_t<T>, string, string, ... : any)
+ onready : function (runner_t<T>, function) : runner_t<T>
+ onready : function (runner_t<T>, function) : runner_t<T>
+ onwaiting : function (runner_t<T>, function) : runner_t<T>
+ onerror : function (runner_t<T>, function) : runner_t<T>
+ end
+ runner : function <T>(function (T), runner_t.watchers_t, any) : runner_t<T>
+ wait_for : function (any) : any, any
+ sleep : function (t:number)
+
+ -- set_nexttick = function(new_next_tick) next_tick = new_next_tick; end;
+ -- set_schedule_function = function (new_schedule_function) schedule_task = new_schedule_function; end;
+end
+return lib
diff --git a/teal-src/prosody/util/bitcompat.d.tl b/teal-src/prosody/util/bitcompat.d.tl
new file mode 100644
index 00000000..18adf725
--- /dev/null
+++ b/teal-src/prosody/util/bitcompat.d.tl
@@ -0,0 +1,8 @@
+local record lib
+ band : function (integer, integer, ... : integer) : integer
+ bor : function (integer, integer, ... : integer) : integer
+ bxor : function (integer, integer, ... : integer) : integer
+ lshift : function (integer, integer) : integer
+ rshift : function (integer, integer) : integer
+end
+return lib
diff --git a/teal-src/util/compat.d.tl b/teal-src/prosody/util/compat.d.tl
index da9c6083..da9c6083 100644
--- a/teal-src/util/compat.d.tl
+++ b/teal-src/prosody/util/compat.d.tl
diff --git a/teal-src/util/crand.d.tl b/teal-src/prosody/util/crand.d.tl
index b40cb67e..b40cb67e 100644
--- a/teal-src/util/crand.d.tl
+++ b/teal-src/prosody/util/crand.d.tl
diff --git a/teal-src/prosody/util/crypto.d.tl b/teal-src/prosody/util/crypto.d.tl
new file mode 100644
index 00000000..cf0b0d1b
--- /dev/null
+++ b/teal-src/prosody/util/crypto.d.tl
@@ -0,0 +1,29 @@
+local record lib
+ record key
+ private_pem : function (key) : string
+ public_pem : function (key) : string
+ get_type : function (key) : string
+ end
+
+ generate_ed25519_keypair : function () : key
+ ed25519_sign : function (key, string) : string
+ ed25519_verify : function (key, string, string) : boolean
+
+ ecdsa_sha256_sign : function (key, string) : string
+ ecdsa_sha256_verify : function (key, string, string) : boolean
+ parse_ecdsa_signature : function (string) : string, string
+ build_ecdsa_signature : function (string, string) : string
+
+ import_private_pem : function (string) : key
+ import_public_pem : function (string) : key
+
+ aes_128_gcm_encrypt : function (key, string, string) : string
+ aes_128_gcm_decrypt : function (key, string, string) : string
+ aes_256_gcm_encrypt : function (key, string, string) : string
+ aes_256_gcm_decrypt : function (key, string, string) : string
+
+
+ version : string
+ _LIBCRYPTO_VERSION : string
+end
+return lib
diff --git a/teal-src/prosody/util/dataforms.d.tl b/teal-src/prosody/util/dataforms.d.tl
new file mode 100644
index 00000000..3dad2776
--- /dev/null
+++ b/teal-src/prosody/util/dataforms.d.tl
@@ -0,0 +1,54 @@
+local stanza_t = require "prosody.util.stanza".stanza_t
+
+local record lib
+ record dataform
+ title : string
+ instructions : string
+
+ record form_field
+
+ enum field_type
+ "boolean"
+ "fixed"
+ "hidden"
+ "jid-multi"
+ "jid-single"
+ "list-multi"
+ "list-single"
+ "text-multi"
+ "text-private"
+ "text-single"
+ end
+
+ type : field_type
+ var : string -- protocol name
+ name : string -- internal name
+
+ label : string
+ desc : string
+
+ datatype : string
+ range_min : number
+ range_max : number
+
+ value : any -- depends on field_type
+ options : table
+ end
+
+ { form_field }
+
+ enum form_type
+ "form"
+ "submit"
+ "cancel"
+ "result"
+ end
+
+ form : function ( dataform, { string : any }, form_type ) : stanza_t
+ data : function ( dataform, stanza_t ) : { string : any }
+ end
+
+ new : function ( dataform ) : dataform
+end
+
+return lib
diff --git a/teal-src/util/datamapper.tl b/teal-src/prosody/util/datamapper.tl
index 73b1dfc0..89d5e29b 100644
--- a/teal-src/util/datamapper.tl
+++ b/teal-src/prosody/util/datamapper.tl
@@ -19,12 +19,14 @@
-- TODO s/number/integer/ once we have appropriate math.type() compat
--
-local st = require "util.stanza";
-local json = require"util.json"
-local pointer = require"util.jsonpointer";
+if not math.type then require "prosody.util.mathcompat" end
+
+local st = require "prosody.util.stanza";
+local json = require "prosody.util.json"
+local pointer = require "prosody.util.jsonpointer";
local json_type_name = json.json_type_name;
-local json_schema_object = require "util.jsonschema"
+local json_schema_object = require "prosody.util.jsonschema"
local type schema_t = boolean | json_schema_object
local function toboolean ( s : string ) : boolean
@@ -133,10 +135,6 @@ local function unpack_propschema( propschema : schema_t, propname : string, curr
end
end
- if current_ns == "urn:xmpp:reactions:0" and name == "reactions" then
- assert(proptype=="array")
- end
-
return proptype, value_where, name, namespace, prefix, single_attribute, enums
end
diff --git a/teal-src/prosody/util/datetime.d.tl b/teal-src/prosody/util/datetime.d.tl
new file mode 100644
index 00000000..9f770a73
--- /dev/null
+++ b/teal-src/prosody/util/datetime.d.tl
@@ -0,0 +1,9 @@
+local record lib
+ date : function (t : number) : string
+ datetime : function (t : number) : string
+ time : function (t : number) : string
+ legacy : function (t : number) : string
+ parse : function (t : string) : number
+end
+
+return lib
diff --git a/teal-src/util/encodings.d.tl b/teal-src/prosody/util/encodings.d.tl
index 58aefa5e..58aefa5e 100644
--- a/teal-src/util/encodings.d.tl
+++ b/teal-src/prosody/util/encodings.d.tl
diff --git a/teal-src/util/error.d.tl b/teal-src/prosody/util/error.d.tl
index 05f52405..4c3a7196 100644
--- a/teal-src/util/error.d.tl
+++ b/teal-src/prosody/util/error.d.tl
@@ -38,7 +38,7 @@ local record protoerror
code : integer
end
-local record error
+local record Error
type : error_type
condition : error_condition
text : string
@@ -55,10 +55,10 @@ local type context = { string : any }
local record error_registry_wrapper
source : string
registry : registry
- new : function (string, context) : error
- coerce : function (any, string) : any, error
- wrap : function (error) : error
- wrap : function (string, context) : error
+ new : function (string, context) : Error
+ coerce : function (any, string) : any, Error
+ wrap : function (Error) : Error
+ wrap : function (string, context) : Error
is_error : function (any) : boolean
end
@@ -66,12 +66,12 @@ local record lib
record configure_opt
auto_inject_traceback : boolean
end
- new : function (protoerror, context, { string : protoerror }, string) : error
+ new : function (protoerror, context, { string : protoerror }, string) : Error
init : function (string, string, registry | compact_registry) : error_registry_wrapper
init : function (string, registry | compact_registry) : error_registry_wrapper
is_error : function (any) : boolean
- coerce : function (any, string) : any, error
- from_stanza : function (table, context, string) : error
+ coerce : function (any, string) : any, Error
+ from_stanza : function (table, context, string) : Error
configure : function
end
diff --git a/teal-src/util/format.d.tl b/teal-src/prosody/util/format.d.tl
index 1ff77c97..1ff77c97 100644
--- a/teal-src/util/format.d.tl
+++ b/teal-src/prosody/util/format.d.tl
diff --git a/teal-src/util/hashes.d.tl b/teal-src/prosody/util/hashes.d.tl
index cbb06f8e..5c249627 100644
--- a/teal-src/util/hashes.d.tl
+++ b/teal-src/prosody/util/hashes.d.tl
@@ -9,10 +9,18 @@ local record lib
sha384 : hash
sha512 : hash
md5 : hash
+ sha3_256 : hash
+ sha3_512 : hash
+ blake2s256 : hash
+ blake2b512 : hash
hmac_sha1 : hmac
hmac_sha256 : hmac
+ hmac_sha224 : hmac
+ hmac_sha384 :hmac
hmac_sha512 : hmac
hmac_md5 : hmac
+ hmac_sha3_256 : hmac
+ hmac_sha3_512 : hmac
scram_Hi_sha1 : kdf
pbkdf2_hmac_sha1 : kdf
pbkdf2_hmac_sha256 : kdf
diff --git a/teal-src/util/hex.d.tl b/teal-src/prosody/util/hex.d.tl
index 3b216a88..9d84540b 100644
--- a/teal-src/util/hex.d.tl
+++ b/teal-src/prosody/util/hex.d.tl
@@ -2,5 +2,7 @@ local type s2s = function (s : string) : string
local record lib
to : s2s
from : s2s
+ encode : s2s
+ decode : s2s
end
return lib
diff --git a/teal-src/util/http.d.tl b/teal-src/prosody/util/http.d.tl
index ecbe35c3..ecbe35c3 100644
--- a/teal-src/util/http.d.tl
+++ b/teal-src/prosody/util/http.d.tl
diff --git a/teal-src/prosody/util/human/io.d.tl b/teal-src/prosody/util/human/io.d.tl
new file mode 100644
index 00000000..e4f64cd1
--- /dev/null
+++ b/teal-src/prosody/util/human/io.d.tl
@@ -0,0 +1,28 @@
+local record lib
+ getchar : function (n : integer) : string
+ getline : function () : string
+ getpass : function () : string
+ show_yesno : function (prompt : string) : boolean
+ read_password : function () : string
+ show_prompt : function (prompt : string) : boolean
+ printf : function (fmt : string, ... : any)
+ padleft : function (s : string, width : integer) : string
+ padright : function (s : string, width : integer) : string
+
+ -- {K:V} vs T ?
+ record tablerow<K,V>
+ width : integer | string -- generate an 1..100 % enum?
+ title : string
+ mapper : function (V, {K:V}) : string
+ key : K
+ enum alignments
+ "left"
+ "right"
+ end
+ align : alignments
+ end
+ type getrow = function<K,V> ({ K : V }) : string
+ table : function<K,V> ({ tablerow<K,V> }, width : integer) : getrow<K,V>
+end
+
+return lib
diff --git a/teal-src/util/human/units.d.tl b/teal-src/prosody/util/human/units.d.tl
index f6568d90..3db17c3a 100644
--- a/teal-src/util/human/units.d.tl
+++ b/teal-src/prosody/util/human/units.d.tl
@@ -1,5 +1,8 @@
local lib = record
+ enum logbase
+ "b" -- 1024
+ end
adjust : function (number, string) : number, string
- format : function (number, string, string) : string
+ format : function (number, string, logbase) : string
end
return lib
diff --git a/teal-src/util/id.d.tl b/teal-src/prosody/util/id.d.tl
index 4b6c93b7..4b6c93b7 100644
--- a/teal-src/util/id.d.tl
+++ b/teal-src/prosody/util/id.d.tl
diff --git a/teal-src/util/interpolation.d.tl b/teal-src/prosody/util/interpolation.d.tl
index fb653edf..fb653edf 100644
--- a/teal-src/util/interpolation.d.tl
+++ b/teal-src/prosody/util/interpolation.d.tl
diff --git a/teal-src/prosody/util/ip.d.tl b/teal-src/prosody/util/ip.d.tl
new file mode 100644
index 00000000..79e901c6
--- /dev/null
+++ b/teal-src/prosody/util/ip.d.tl
@@ -0,0 +1,20 @@
+local record iplib
+ enum protocol
+ "IPv6"
+ "IPv4"
+ end
+ record ip_t
+ addr : string
+ packed : string
+ proto : protocol
+ zone : string
+ end
+
+ new_ip : function (string, protocol) : ip_t
+ commonPrefixLength : function (ip_t, ip_t) : integer
+ parse_cidr : function (string) : ip_t, integer
+ match : function (ip_t, ip_t, integer) : boolean
+ is_ip : function (any) : boolean
+ truncate : function (ip_t, integer) : ip_t
+end
+return iplib
diff --git a/teal-src/util/jid.d.tl b/teal-src/prosody/util/jid.d.tl
index 897318d9..897318d9 100644
--- a/teal-src/util/jid.d.tl
+++ b/teal-src/prosody/util/jid.d.tl
diff --git a/teal-src/util/json.d.tl b/teal-src/prosody/util/json.d.tl
index a1c25004..a1c25004 100644
--- a/teal-src/util/json.d.tl
+++ b/teal-src/prosody/util/json.d.tl
diff --git a/teal-src/util/jsonpointer.tl b/teal-src/prosody/util/jsonpointer.tl
index c21e1fbf..c21e1fbf 100644
--- a/teal-src/util/jsonpointer.tl
+++ b/teal-src/prosody/util/jsonpointer.tl
diff --git a/teal-src/util/jsonschema.tl b/teal-src/prosody/util/jsonschema.tl
index 160c164c..a1dd3cae 100644
--- a/teal-src/util/jsonschema.tl
+++ b/teal-src/prosody/util/jsonschema.tl
@@ -1,4 +1,4 @@
--- Copyright (C) 2021 Kim Alvefur
+-- Copyright (C) Kim Alvefur
--
-- This project is MIT/X11 licensed. Please see the
-- COPYING file in the source package for more information.
@@ -8,10 +8,19 @@
-- https://json-schema.org/draft/2020-12/json-schema-validation.html
--
-local json = require"util.json"
+if not math.type then require "prosody.util.mathcompat" end
+
+
+local utf8 = rawget(_G, "utf8") or require"prosody.util.encodings".utf8;
+local utf8_len = utf8.len or function(s)
+ local _, count = s:gsub("[%z\001-\127\194-\253][\128-\191]*", "");
+ return count;
+end;
+
+local json = require "prosody.util.json"
local null = json.null;
-local pointer = require "util.jsonpointer"
+local pointer = require "prosody.util.jsonpointer"
local type json_type_name = json.json_type_name
@@ -22,20 +31,49 @@ local record json_schema_object
type json_type_name = json.json_type_name
type schema_object = json_schema_object
- type : json_type_name | { json_type_name }
- enum : { any }
- const : any
+ -- json-schema-core meta stuff
+ ["$schema"] : string
+ ["$vocabulary"] : { string : boolean }
+ ["$id"] : string
+ ["$comment"] : string
+ ["$defs"] : { string : schema_t }
+ ["$anchor"] : string -- NYI
+ ["$dynamicAnchor"] : string -- NYI
+ ["$ref"] : string
+ ["$dynamicRef"] : string -- NYI
+ -- combinations
allOf : { schema_t }
anyOf : { schema_t }
oneOf : { schema_t }
+ -- conditional logic
["not"] : schema_t
["if"] : schema_t
["then"] : schema_t
["else"] : schema_t
- ["$ref"] : string
+ dependentRequired : { string : { string } }
+
+ -- arrays
+ prefixItems : { schema_t }
+ items : schema_t
+ contains : schema_t
+
+ -- objects
+ properties : { string : schema_t }
+ patternProperties: { string : schema_t } -- NYI
+ additionalProperties: schema_t
+ propertyNames : schema_t
+
+ -- unevaluated
+ unevaluatedItems : schema_t -- NYI
+ unevaluatedProperties : schema_t -- NYI
+
+ -- json-schema-validation
+ type : json_type_name | { json_type_name }
+ enum : { any }
+ const : any
-- numbers
multipleOf : number
@@ -48,27 +86,26 @@ local record json_schema_object
maxLength : integer
minLength : integer
pattern : string -- NYI
- format : string
-- arrays
- prefixItems : { schema_t }
- items : schema_t
- contains : schema_t
maxItems : integer
minItems : integer
uniqueItems : boolean
- maxContains : integer -- NYI
- minContains : integer -- NYI
+ maxContains : integer
+ minContains : integer
-- objects
- properties : { string : schema_t }
maxProperties : integer -- NYI
minProperties : integer -- NYI
required : { string }
- dependentRequired : { string : { string } }
- additionalProperties: schema_t
- patternProperties: schema_t -- NYI
- propertyNames : schema_t
+ dependentSchemas : { string : schema_t }
+
+ -- semantic format
+ format : string
+
+ -- for Lua
+ luaPatternProperties: { string : schema_t }
+ luaPattern : string
-- xml
record xml_t
@@ -190,10 +227,13 @@ function complex_validate (schema : json_schema_object, data : any, root : json_
-- XXX this is measured in byte, while JSON measures in ... bork
-- TODO use utf8.len?
if data is string then
- if schema.maxLength and #data > schema.maxLength then
+ if schema.maxLength and utf8_len(data) > schema.maxLength then
+ return false
+ end
+ if schema.minLength and utf8_len(data) < schema.minLength then
return false
end
- if schema.minLength and #data < schema.minLength then
+ if schema.luaPattern and not data:match(schema.luaPattern) then
return false
end
end
@@ -276,6 +316,9 @@ function complex_validate (schema : json_schema_object, data : any, root : json_
end
if data is table then
+ -- tables combine object and array behavior, thus we do both kinds of
+ -- validations in this block, which could be useful for validating Lua
+ -- tables
if schema.maxItems and #data > schema.maxItems then
return false
@@ -293,7 +336,20 @@ function complex_validate (schema : json_schema_object, data : any, root : json_
end
end
+ if schema.dependentRequired then
+ for k, reqs in pairs(schema.dependentRequired) do
+ if data[k] ~= nil then
+ for _, req in ipairs(reqs) do
+ if data[req] == nil then
+ return false
+ end
+ end
+ end
+ end
+ end
+
if schema.propertyNames ~= nil then
+ -- could be used to validate non-string keys of Lua tables
for k in pairs(data) do
if not validate(schema.propertyNames, k, root) then
return false
@@ -301,17 +357,37 @@ function complex_validate (schema : json_schema_object, data : any, root : json_
end
end
+ -- additionalProperties applies to properties not validated by properties
+ -- or patternProperties, so we must keep track of properties validated by
+ -- the later
+ local seen_properties : { string : boolean } = {}
+
if schema.properties then
for k, sub in pairs(schema.properties) do
if data[k] ~= nil and not validate(sub, data[k], root) then
return false
end
+ seen_properties[k] = true
+ end
+ end
+
+ if schema.luaPatternProperties then
+ -- like patternProperties, but Lua patterns
+ for pattern, sub in pairs(schema.luaPatternProperties) do
+ for k in pairs(data) do
+ if k is string and k:match(pattern) then
+ if not validate(sub, data[k], root) then
+ return false
+ end
+ seen_properties[k] = true
+ end
+ end
end
end
if schema.additionalProperties ~= nil then
for k, v in pairs(data) do
- if schema.properties == nil or schema.properties[k as string] == nil then
+ if not seen_properties[k as string] then
if not validate(schema.additionalProperties, v, root) then
return false
end
@@ -319,6 +395,14 @@ function complex_validate (schema : json_schema_object, data : any, root : json_
end
end
+ if schema.dependentSchemas then
+ for k, sub in pairs(schema.dependentSchemas) do
+ if data[k] ~= nil and not validate(sub, data, root) then
+ return false
+ end
+ end
+ end
+
if schema.uniqueItems then
-- only works for scalars, would need to deep-compare for objects/arrays/tables
local values : { any : boolean } = {}
@@ -352,14 +436,13 @@ function complex_validate (schema : json_schema_object, data : any, root : json_
end
if schema.contains ~= nil then
- local found = false
+ local found = 0
for i = 1, #data do
if validate(schema.contains, data[i], root) then
- found = true
- break
+ found = found + 1
end
end
- if not found then
+ if found < (schema.minContains or 1) or found > (schema.maxContains or math.huge) then
return false
end
end
diff --git a/teal-src/prosody/util/jwt.d.tl b/teal-src/prosody/util/jwt.d.tl
new file mode 100644
index 00000000..b3d0cd9e
--- /dev/null
+++ b/teal-src/prosody/util/jwt.d.tl
@@ -0,0 +1,38 @@
+local crypto = require "prosody.util.crypto"
+local record jwtlib
+ enum algorithm
+ "HS256"
+ "HS384"
+ "HS512"
+ "ES256"
+ "ES512"
+ "RS256"
+ "RS384"
+ "RS512"
+ "PS256"
+ "PS384"
+ "PS512"
+ end
+ type payload = { string : any }
+ type signer_t = function (payload : payload) : string
+ type verifier_t = function (token : string) : payload
+ enum key_type
+ "rsaEncryption"
+ "id-ecPublicKey"
+ end
+ record algorithm_t
+ sign : signer_t
+ verify : verifier_t
+ load_key : function (key : string) : crypto.key
+ end
+ init : function (algorithm, private_key : string, public_key : string, table) : signer_t, verifier_t
+ new_signer : function (algorithm, string, table) : signer_t
+ new_verifier : function (algorithm, string, table) : verifier_t
+ _algorithms : {
+ algorithm : algorithm_t
+ }
+ -- Deprecated
+ sign : function (private_key : string, payload) : string
+ verify : function (string) : payload
+end
+return jwtlib
diff --git a/teal-src/prosody/util/logger.d.tl b/teal-src/prosody/util/logger.d.tl
new file mode 100644
index 00000000..db29adfd
--- /dev/null
+++ b/teal-src/prosody/util/logger.d.tl
@@ -0,0 +1,18 @@
+local record util
+ enum loglevel
+ "debug"
+ "info"
+ "warn"
+ "error"
+ end
+ type logger = function ( loglevel, string, ...:any )
+ type sink = function ( string, loglevel, string, ...:any )
+ type simple_sink = function ( string, loglevel, string )
+ init : function ( string ) : logger
+ make_logger : function ( string, loglevel ) : function ( string, ...:any )
+ reset : function ()
+ add_level_sink : function ( loglevel, sink )
+ add_simple_sink : function ( simple_sink, { loglevel } )
+end
+
+return util
diff --git a/teal-src/prosody/util/mathcompat.tl b/teal-src/prosody/util/mathcompat.tl
new file mode 100644
index 00000000..1e3f9bab
--- /dev/null
+++ b/teal-src/prosody/util/mathcompat.tl
@@ -0,0 +1,15 @@
+if not math.type then
+ local enum number_subtype
+ "float" "integer"
+ end
+ local function math_type(t:any) : number_subtype
+ if t is number then
+ if t % 1 == 0 and t ~= t+1 and t ~= t-1 then
+ return "integer"
+ else
+ return "float"
+ end
+ end
+ end
+ _G.math.type = math_type
+end
diff --git a/teal-src/util/net.d.tl b/teal-src/prosody/util/net.d.tl
index 1040fcef..1040fcef 100644
--- a/teal-src/util/net.d.tl
+++ b/teal-src/prosody/util/net.d.tl
diff --git a/teal-src/util/poll.d.tl b/teal-src/prosody/util/poll.d.tl
index 8df56d57..8df56d57 100644
--- a/teal-src/util/poll.d.tl
+++ b/teal-src/prosody/util/poll.d.tl
diff --git a/teal-src/util/pposix.d.tl b/teal-src/prosody/util/pposix.d.tl
index 68f49730..68f49730 100644
--- a/teal-src/util/pposix.d.tl
+++ b/teal-src/prosody/util/pposix.d.tl
diff --git a/teal-src/prosody/util/promise.d.tl b/teal-src/prosody/util/promise.d.tl
new file mode 100644
index 00000000..d895a828
--- /dev/null
+++ b/teal-src/prosody/util/promise.d.tl
@@ -0,0 +1,22 @@
+
+local record lib
+ type resolve_func = function (any)
+ type promise_body = function (resolve_func, resolve_func)
+
+ record Promise<A, B>
+ type on_resolved = function (A) : any
+ type on_rejected = function (B) : any
+ next : function (Promise, on_resolved, on_rejected) : Promise<any, any>
+ end
+
+ new : function (promise_body) : Promise
+ resolve : function (any) : Promise
+ reject : function (any) : Promise
+ all : function ({ Promise }) : Promise
+ all_settled : function ({ Promise }) : Promise
+ race : function ({ Promise }) : Promise
+ try : function
+ is_promise : function(any) : boolean
+end
+
+return lib
diff --git a/teal-src/prosody/util/queue.d.tl b/teal-src/prosody/util/queue.d.tl
new file mode 100644
index 00000000..cb8458e7
--- /dev/null
+++ b/teal-src/prosody/util/queue.d.tl
@@ -0,0 +1,21 @@
+local record lib
+ record queue<T>
+ size : integer
+ count : function (queue<T>) : integer
+ enum push_errors
+ "queue full"
+ end
+
+ push : function (queue<T>, T) : boolean, push_errors
+ pop : function (queue<T>) : T
+ peek : function (queue<T>) : T
+ replace : function (queue<T>, T) : boolean, push_errors
+ type iterator = function (T, integer) : integer, T
+ items : function (queue<T>) : iterator, T, integer
+ type consume_iter = function (queue<T>) : T
+ consume : function (queue<T>) : consume_iter
+ end
+
+ new : function<T> (size:integer, allow_wrapping:boolean) : queue<T>
+end
+return lib;
diff --git a/teal-src/util/random.d.tl b/teal-src/prosody/util/random.d.tl
index 83ff2fcc..83ff2fcc 100644
--- a/teal-src/util/random.d.tl
+++ b/teal-src/prosody/util/random.d.tl
diff --git a/teal-src/util/ringbuffer.d.tl b/teal-src/prosody/util/ringbuffer.d.tl
index e4726d68..e4726d68 100644
--- a/teal-src/util/ringbuffer.d.tl
+++ b/teal-src/prosody/util/ringbuffer.d.tl
diff --git a/teal-src/prosody/util/roles.d.tl b/teal-src/prosody/util/roles.d.tl
new file mode 100644
index 00000000..fef4f88a
--- /dev/null
+++ b/teal-src/prosody/util/roles.d.tl
@@ -0,0 +1,32 @@
+local record util_roles
+
+ type context = any
+
+ record Role
+ id : string
+ name : string
+ description : string
+ default : boolean
+ priority : number -- or integer?
+ permissions : { string : boolean }
+
+ may : function (Role, string, context)
+ clone : function (Role, role_config)
+ set_permission : function (Role, string, boolean, boolean)
+ end
+
+ is_role : function (any) : boolean
+
+ record role_config
+ name : string
+ description : string
+ default : boolean
+ priority : number -- or integer?
+ inherits : { Role }
+ permissions : { string : boolean }
+ end
+
+ new : function (role_config, Role) : Role
+end
+
+return util_roles
diff --git a/teal-src/prosody/util/serialization.d.tl b/teal-src/prosody/util/serialization.d.tl
new file mode 100644
index 00000000..27f100c0
--- /dev/null
+++ b/teal-src/prosody/util/serialization.d.tl
@@ -0,0 +1,33 @@
+local record _M
+ enum preset
+ "debug"
+ "oneline"
+ "compact"
+ end
+ type fallback = function (any, string) : string
+ record config
+ preset : preset
+ fallback : fallback
+ fatal : boolean
+ keywords : { string : boolean }
+ indentwith : string
+ itemstart : string
+ itemsep : string
+ itemlast : string
+ tstart : string
+ tend : string
+ kstart : string
+ kend : string
+ equals : string
+ unquoted : boolean | string
+ hex : string
+ freeze : boolean
+ maxdepth : integer
+ multirefs : boolean
+ table_pairs : function
+ end
+ type serializer = function (any) : string
+ new : function (config|preset) : serializer
+ serialize : function (any, config|preset) : string
+end
+return _M
diff --git a/teal-src/prosody/util/set.d.tl b/teal-src/prosody/util/set.d.tl
new file mode 100644
index 00000000..a23dd258
--- /dev/null
+++ b/teal-src/prosody/util/set.d.tl
@@ -0,0 +1,22 @@
+local record lib
+ record Set<T>
+ add : function<T> (Set<T>, T)
+ contains : function<T> (Set<T>, T) : boolean
+ contains_set : function<T> (Set<T>, Set<T>) : boolean
+ items : function<T> (Set<T>) : function<T> (Set<T>, T) : T
+ remove : function<T> (Set<T>, T)
+ add_list : function<T> (Set<T>, { T })
+ include : function<T> (Set<T>, Set<T>)
+ exclude : function<T> (Set<T>, Set<T>)
+ empty : function<T> (Set<T>) : boolean
+ end
+
+ new : function<T> ({ T }) : Set<T>
+ is_set : function (any) : boolean
+ union : function<T> (Set<T>, Set<T>) : Set <T>
+ difference : function<T> (Set<T>, Set<T>) : Set <T>
+ intersection : function<T> (Set<T>, Set<T>) : Set <T>
+ xor : function<T> (Set<T>, Set<T>) : Set <T>
+end
+
+return lib
diff --git a/teal-src/util/signal.d.tl b/teal-src/prosody/util/signal.d.tl
index 8610aa7f..290cf08f 100644
--- a/teal-src/util/signal.d.tl
+++ b/teal-src/prosody/util/signal.d.tl
@@ -1,5 +1,5 @@
local record lib
- enum signal
+ enum Signal
"SIGABRT"
"SIGALRM"
"SIGBUS"
@@ -33,9 +33,9 @@ local record lib
"SIGXCPU"
"SIGXFSZ"
end
- signal : function (integer | signal, function, boolean) : boolean
- raise : function (integer | signal)
- kill : function (integer, integer | signal)
+ signal : function (integer | Signal, function, boolean) : boolean
+ raise : function (integer | Signal)
+ kill : function (integer, integer | Signal)
-- enum : integer
end
return lib
diff --git a/teal-src/util/smqueue.tl b/teal-src/prosody/util/smqueue.tl
index e149dde7..821aee57 100644
--- a/teal-src/util/smqueue.tl
+++ b/teal-src/prosody/util/smqueue.tl
@@ -1,4 +1,4 @@
-local queue = require "util.queue";
+local queue = require "prosody.util.queue";
local record lib
-- T would typically be util.stanza
diff --git a/teal-src/util/stanza.d.tl b/teal-src/prosody/util/stanza.d.tl
index a358248a..e1ab2105 100644
--- a/teal-src/util/stanza.d.tl
+++ b/teal-src/prosody/util/stanza.d.tl
@@ -4,6 +4,39 @@ local record lib
type childtags_iter = function () : stanza_t
type maptags_cb = function ( stanza_t ) : stanza_t
+
+ enum stanza_error_type
+ "auth"
+ "cancel"
+ "continue"
+ "modify"
+ "wait"
+ end
+ enum stanza_error_condition
+ "bad-request"
+ "conflict"
+ "feature-not-implemented"
+ "forbidden"
+ "gone"
+ "internal-server-error"
+ "item-not-found"
+ "jid-malformed"
+ "not-acceptable"
+ "not-allowed"
+ "not-authorized"
+ "policy-violation"
+ "recipient-unavailable"
+ "redirect"
+ "registration-required"
+ "remote-server-not-found"
+ "remote-server-timeout"
+ "resource-constraint"
+ "service-unavailable"
+ "subscription-required"
+ "undefined-condition"
+ "unexpected-request"
+ end
+
record stanza_t
name : string
attr : { string : string }
@@ -16,6 +49,7 @@ local record lib
tag : function ( stanza_t, string, { string : string } ) : stanza_t
text : function ( stanza_t, string ) : stanza_t
up : function ( stanza_t ) : stanza_t
+ at_top : function ( stanza_t ) : boolean
reset : function ( stanza_t ) : stanza_t
add_direct_child : function ( stanza_t, stanza_t )
add_child : function ( stanza_t, stanza_t )
@@ -24,6 +58,8 @@ local record lib
get_child : function ( stanza_t, string, string ) : stanza_t
get_text : function ( stanza_t ) : string
get_child_text : function ( stanza_t, string, string ) : string
+ get_child_attr : function ( stanza_t, string, string ) : string
+ get_child_with_attr : function ( stanza_t, string, string, string, function (string) : boolean ) : string
child_with_name : function ( stanza_t, string, string ) : stanza_t
child_with_ns : function ( stanza_t, string, string ) : stanza_t
children : function ( stanza_t ) : children_iter, stanza_t, integer
@@ -35,7 +71,9 @@ local record lib
pretty_print : function ( stanza_t ) : string
pretty_top_tag : function ( stanza_t ) : string
- get_error : function ( stanza_t ) : string, string, string, stanza_t
+ -- FIXME Represent util.error support
+ get_error : function ( stanza_t ) : stanza_error_type, stanza_error_condition, string, stanza_t
+ add_error : function ( stanza_t, stanza_error_type, stanza_error_condition, string, string )
indent : function ( stanza_t, integer, string ) : stanza_t
end
@@ -45,16 +83,61 @@ local record lib
{ serialized_stanza_t | string }
end
+ record message_attr
+ ["xml:lang"] : string
+ from : string
+ id : string
+ to : string
+ type : message_type
+ enum message_type
+ "chat"
+ "error"
+ "groupchat"
+ "headline"
+ "normal"
+ end
+ end
+
+ record presence_attr
+ ["xml:lang"] : string
+ from : string
+ id : string
+ to : string
+ type : presence_type
+ enum presence_type
+ "error"
+ "probe"
+ "subscribe"
+ "subscribed"
+ "unsubscribe"
+ "unsubscribed"
+ end
+ end
+
+ record iq_attr
+ ["xml:lang"] : string
+ from : string
+ id : string
+ to : string
+ type : iq_type
+ enum iq_type
+ "error"
+ "get"
+ "result"
+ "set"
+ end
+ end
+
stanza : function ( string, { string : string } ) : stanza_t
is_stanza : function ( any ) : boolean
preserialize : function ( stanza_t ) : serialized_stanza_t
deserialize : function ( serialized_stanza_t ) : stanza_t
clone : function ( stanza_t, boolean ) : stanza_t
- message : function ( { string : string }, string ) : stanza_t
- iq : function ( { string : string } ) : stanza_t
+ message : function ( message_attr, string ) : stanza_t
+ iq : function ( iq_attr ) : stanza_t
reply : function ( stanza_t ) : stanza_t
- error_reply : function ( stanza_t, string, string, string, string )
- presence : function ( { string : string } ) : stanza_t
+ error_reply : function ( stanza_t, stanza_error_type, stanza_error_condition, string, string ) : stanza_t
+ presence : function ( presence_attr ) : stanza_t
xml_escape : function ( string ) : string
pretty_print : function ( string ) : string
end
diff --git a/teal-src/util/strbitop.d.tl b/teal-src/prosody/util/strbitop.d.tl
index 010efdb8..010efdb8 100644
--- a/teal-src/util/strbitop.d.tl
+++ b/teal-src/prosody/util/strbitop.d.tl
diff --git a/teal-src/prosody/util/struct.d.tl b/teal-src/prosody/util/struct.d.tl
new file mode 100644
index 00000000..201aaa23
--- /dev/null
+++ b/teal-src/prosody/util/struct.d.tl
@@ -0,0 +1,6 @@
+local record lib
+ pack : function (string, ...:any) : string
+ unpack : function(string, string, integer) : any...
+ size : function(string) : integer
+end
+return lib
diff --git a/teal-src/util/table.d.tl b/teal-src/prosody/util/table.d.tl
index 0ff5ed95..67e5d0f0 100644
--- a/teal-src/util/table.d.tl
+++ b/teal-src/prosody/util/table.d.tl
@@ -1,6 +1,7 @@
local record lib
create : function (narr:integer, nrec:integer):table
pack : function (...:any):{any}
+ move : function (table, integer, integer, integer, table) : table
end
return lib
diff --git a/teal-src/prosody/util/termcolours.d.tl b/teal-src/prosody/util/termcolours.d.tl
new file mode 100644
index 00000000..226259aa
--- /dev/null
+++ b/teal-src/prosody/util/termcolours.d.tl
@@ -0,0 +1,7 @@
+local record lib
+ getstring : function (string, string) : string
+ getstyle : function (...:string) : string
+ setstyle : function (string) : string
+ tohtml : function (string) : string
+end
+return lib
diff --git a/teal-src/util/time.d.tl b/teal-src/prosody/util/time.d.tl
index e159706b..e159706b 100644
--- a/teal-src/util/time.d.tl
+++ b/teal-src/prosody/util/time.d.tl
diff --git a/teal-src/prosody/util/timer.d.tl b/teal-src/prosody/util/timer.d.tl
new file mode 100644
index 00000000..a6394cf3
--- /dev/null
+++ b/teal-src/prosody/util/timer.d.tl
@@ -0,0 +1,8 @@
+local record util_timer
+ record task end
+ type timer_callback = function (number) : number
+ add_task : function ( number, timer_callback, any ) : task
+ stop : function ( task )
+ reschedule : function ( task, number ) : task
+end
+return util_timer
diff --git a/teal-src/util/uuid.d.tl b/teal-src/prosody/util/uuid.d.tl
index 45fd4312..284a4e4c 100644
--- a/teal-src/util/uuid.d.tl
+++ b/teal-src/prosody/util/uuid.d.tl
@@ -1,5 +1,5 @@
local record lib
- get_nibbles : (number) : string
+ get_nibbles : function (number) : string
generate : function () : string
seed : function (string)
diff --git a/teal-src/util/xtemplate.tl b/teal-src/prosody/util/xtemplate.tl
index b3bdc400..7f3b513a 100644
--- a/teal-src/util/xtemplate.tl
+++ b/teal-src/prosody/util/xtemplate.tl
@@ -14,7 +14,7 @@ local s_match = string.match;
local s_sub = string.sub;
local t_concat = table.concat;
-local st = require "util.stanza";
+local st = require "prosody.util.stanza";
local type escape_t = function (string) : string
local type filter_t = function (string, string | st.stanza_t, string) : string | st.stanza_t, boolean
diff --git a/teal-src/util/dataforms.d.tl b/teal-src/util/dataforms.d.tl
deleted file mode 100644
index 9e4170fa..00000000
--- a/teal-src/util/dataforms.d.tl
+++ /dev/null
@@ -1,52 +0,0 @@
-local stanza_t = require "util.stanza".stanza_t
-
-local enum form_type
- "form"
- "submit"
- "cancel"
- "result"
-end
-
-local enum field_type
- "boolean"
- "fixed"
- "hidden"
- "jid-multi"
- "jid-single"
- "list-multi"
- "list-single"
- "text-multi"
- "text-private"
- "text-single"
-end
-
-local record form_field
-
- type : field_type
- var : string -- protocol name
- name : string -- internal name
-
- label : string
- desc : string
-
- datatype : string
- range_min : number
- range_max : number
-
- value : any -- depends on field_type
- options : table
-end
-
-local record dataform
- title : string
- instructions : string
- { form_field } -- XXX https://github.com/teal-language/tl/pull/415
-
- form : function ( dataform, table, form_type ) : stanza_t
-end
-
-local record lib
- new : function ( dataform ) : dataform
-end
-
-return lib
diff --git a/teal-src/util/datetime.d.tl b/teal-src/util/datetime.d.tl
deleted file mode 100644
index 971e8f9c..00000000
--- a/teal-src/util/datetime.d.tl
+++ /dev/null
@@ -1,11 +0,0 @@
--- TODO s/number/integer/ once Teal gets support for that
-
-local record lib
- date : function (t : integer) : string
- datetime : function (t : integer) : string
- time : function (t : integer) : string
- legacy : function (t : integer) : string
- parse : function (t : string) : integer
-end
-
-return lib