luci-base: luci.js, rpc.js, uci.js, network.js: add JSDoc annotations
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
parent
93934c08ca
commit
b2809cebd8
4 changed files with 4045 additions and 30 deletions
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -5,7 +5,17 @@ var rpcRequestID = 1,
|
|||
rpcBaseURL = L.url('admin/ubus'),
|
||||
rpcInterceptorFns = [];
|
||||
|
||||
return L.Class.extend({
|
||||
/**
|
||||
* @class rpc
|
||||
* @memberof LuCI
|
||||
* @hideconstructor
|
||||
* @classdesc
|
||||
*
|
||||
* The `LuCI.rpc` class provides high level ubus JSON-RPC abstractions
|
||||
* and means for listing and invoking remove RPC methods.
|
||||
*/
|
||||
return L.Class.extend(/** @lends LuCI.rpc.prototype */ {
|
||||
/* privates */
|
||||
call: function(req, cb, nobatch) {
|
||||
var q = '';
|
||||
|
||||
|
@ -106,6 +116,27 @@ return L.Class.extend({
|
|||
req.resolve(ret);
|
||||
},
|
||||
|
||||
/**
|
||||
* Lists available remote ubus objects or the method signatures of
|
||||
* specific objects.
|
||||
*
|
||||
* This function has two signatures and is sensitive to the number of
|
||||
* arguments passed to it:
|
||||
* - `list()` -
|
||||
* Returns an array containing the names of all remote `ubus` objects
|
||||
* - `list("objname", ...)`
|
||||
* Returns method signatures for each given `ubus` object name.
|
||||
*
|
||||
* @param {...string} [objectNames]
|
||||
* If any object names are given, this function will return the method
|
||||
* signatures of each given object.
|
||||
*
|
||||
* @returns {Promise<Array<string>|Object<string, Object<string, Object<string, string>>>>}
|
||||
* When invoked without arguments, this function will return a promise
|
||||
* resolving to an array of `ubus` object names. When invoked with one or
|
||||
* more arguments, a promise resolving to an object describing the method
|
||||
* signatures of each requested `ubus` object name will be returned.
|
||||
*/
|
||||
list: function() {
|
||||
var msg = {
|
||||
jsonrpc: '2.0',
|
||||
|
@ -126,6 +157,138 @@ return L.Class.extend({
|
|||
}, this));
|
||||
},
|
||||
|
||||
/**
|
||||
* @typedef {Object} DeclareOptions
|
||||
* @memberof LuCI.rpc
|
||||
*
|
||||
* @property {string} object
|
||||
* The name of the remote `ubus` object to invoke.
|
||||
*
|
||||
* @property {string} method
|
||||
* The name of the remote `ubus` method to invoke.
|
||||
*
|
||||
* @property {string[]} [params]
|
||||
* Lists the named parameters expected by the remote `ubus` RPC method.
|
||||
* The arguments passed to the resulting generated method call function
|
||||
* will be mapped to named parameters in the order they appear in this
|
||||
* array.
|
||||
*
|
||||
* Extraneous parameters passed to the generated function will not be
|
||||
* sent to the remote procedure but are passed to the
|
||||
* {@link LuCI.rpc~filterFn filter function} if one is specified.
|
||||
*
|
||||
* Examples:
|
||||
* - `params: [ "foo", "bar" ]` -
|
||||
* When the resulting call function is invoked with `fn(true, false)`,
|
||||
* the corresponding args object sent to the remote procedure will be
|
||||
* `{ foo: true, bar: false }`.
|
||||
* - `params: [ "test" ], filter: function(reply, args, extra) { ... }` -
|
||||
* When the resultung generated function is invoked with
|
||||
* `fn("foo", "bar", "baz")` then `{ "test": "foo" }` will be sent as
|
||||
* argument to the remote procedure and the filter function will be
|
||||
* invoked with `filterFn(reply, [ "foo" ], "bar", "baz")`
|
||||
*
|
||||
* @property {Object<string,*>} [expect]
|
||||
* Describes the expected return data structure. The given object is
|
||||
* supposed to contain a single key selecting the value to use from
|
||||
* the returned `ubus` reply object. The value of the sole key within
|
||||
* the `expect` object is used to infer the expected type of the received
|
||||
* `ubus` reply data.
|
||||
*
|
||||
* If the received data does not contain `expect`'s key, or if the
|
||||
* type of the data differs from the type of the value in the expect
|
||||
* object, the expect object's value is returned as default instead.
|
||||
*
|
||||
* The key in the `expect` object may be an empty string (`''`) in which
|
||||
* case the entire reply object is selected instead of one of its subkeys.
|
||||
*
|
||||
* If the `expect` option is omitted, the received reply will be returned
|
||||
* as-is, regardless of its format or type.
|
||||
*
|
||||
* Examples:
|
||||
* - `expect: { '': { error: 'Invalid response' } }` -
|
||||
* This requires the entire `ubus` reply to be a plain JavaScript
|
||||
* object. If the reply isn't an object but e.g. an array or a numeric
|
||||
* error code instead, it will get replaced with
|
||||
* `{ error: 'Invalid response' }` instead.
|
||||
* - `expect: { results: [] }` -
|
||||
* This requires the received `ubus` reply to be an object containing
|
||||
* a key `results` with an array as value. If the received reply does
|
||||
* not contain such a key, or if `reply.results` points to a non-array
|
||||
* value, the empty array (`[]`) will be used instead.
|
||||
* - `expect: { success: false }` -
|
||||
* This requires the received `ubus` reply to be an object containing
|
||||
* a key `success` with a boolean value. If the reply does not contain
|
||||
* `success` or if `reply.success` is not a boolean value, `false` will
|
||||
* be returned as default instead.
|
||||
*
|
||||
* @property {LuCI.rpc~filterFn} [filter]
|
||||
* Specfies an optional filter function which is invoked to transform the
|
||||
* received reply data before it is returned to the caller.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* The filter function is invoked to transform a received `ubus` RPC call
|
||||
* reply before returning it to the caller.
|
||||
*
|
||||
* @callback LuCI.rpc~filterFn
|
||||
*
|
||||
* @param {*} data
|
||||
* The received `ubus` reply data or a subset of it as described in the
|
||||
* `expect` option of the RPC call declaration. In case of remote call
|
||||
* errors, `data` is numeric `ubus` error code instead.
|
||||
*
|
||||
* @param {Array<*>} args
|
||||
* The arguments the RPC method has been invoked with.
|
||||
*
|
||||
* @param {...*} extraArgs
|
||||
* All extraneous arguments passed to the RPC method exceeding the number
|
||||
* of arguments describes in the RPC call declaration.
|
||||
*
|
||||
* @return {*}
|
||||
* The return value of the filter function will be returned to the caller
|
||||
* of the RPC method as-is.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The generated invocation function is returned by
|
||||
* {@link LuCI.rpc#declare rpc.declare()} and encapsulates a single
|
||||
* RPC method call.
|
||||
*
|
||||
* Calling this function will execute a remote `ubus` HTTP call request
|
||||
* using the arguments passed to it as arguments and return a promise
|
||||
* resolving to the received reply values.
|
||||
*
|
||||
* @callback LuCI.rpc~invokeFn
|
||||
*
|
||||
* @param {...*} params
|
||||
* The parameters to pass to the remote procedure call. The given
|
||||
* positional arguments will be named to named RPC parameters according
|
||||
* to the names specified in the `params` array of the method declaration.
|
||||
*
|
||||
* Any additional parameters exceeding the amount of arguments in the
|
||||
* `params` declaration are passed as private extra arguments to the
|
||||
* declared filter function.
|
||||
*
|
||||
* @return {Promise<*>}
|
||||
* Returns a promise resolving to the result data of the remote `ubus`
|
||||
* RPC method invocation, optionally substituted and filtered according
|
||||
* to the `expect` and `filter` declarations.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Describes a remote RPC call procedure and returns a function
|
||||
* implementing it.
|
||||
*
|
||||
* @param {LuCI.rpc.DeclareOptions} options
|
||||
* If any object names are given, this function will return the method
|
||||
* signatures of each given object.
|
||||
*
|
||||
* @returns {LuCI.rpc~invokeFn}
|
||||
* Returns a new function implementing the method call described in
|
||||
* `options`.
|
||||
*/
|
||||
declare: function(options) {
|
||||
return Function.prototype.bind.call(function(rpc, options) {
|
||||
var args = this.varargs(arguments, 2);
|
||||
|
@ -173,22 +336,58 @@ return L.Class.extend({
|
|||
}, this, this, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the current RPC session id.
|
||||
*
|
||||
* @returns {string}
|
||||
* Returns the 32 byte session ID string used for authenticating remote
|
||||
* requests.
|
||||
*/
|
||||
getSessionID: function() {
|
||||
return rpcSessionID;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the RPC session id to use.
|
||||
*
|
||||
* @param {string} sid
|
||||
* Sets the 32 byte session ID string used for authenticating remote
|
||||
* requests.
|
||||
*/
|
||||
setSessionID: function(sid) {
|
||||
rpcSessionID = sid;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the current RPC base URL.
|
||||
*
|
||||
* @returns {string}
|
||||
* Returns the RPC URL endpoint to issue requests against.
|
||||
*/
|
||||
getBaseURL: function() {
|
||||
return rpcBaseURL;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the RPC base URL to use.
|
||||
*
|
||||
* @param {string} sid
|
||||
* Sets the RPC URL endpoint to issue requests against.
|
||||
*/
|
||||
setBaseURL: function(url) {
|
||||
rpcBaseURL = url;
|
||||
},
|
||||
|
||||
/**
|
||||
* Translates a numeric `ubus` error code into a human readable
|
||||
* description.
|
||||
*
|
||||
* @param {number} statusCode
|
||||
* The numeric status code.
|
||||
*
|
||||
* @returns {string}
|
||||
* Returns the textual description of the code.
|
||||
*/
|
||||
getStatusText: function(statusCode) {
|
||||
switch (statusCode) {
|
||||
case 0: return _('Command OK');
|
||||
|
@ -206,12 +405,68 @@ return L.Class.extend({
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Registered interceptor functions are invoked before the standard reply
|
||||
* parsing and handling logic.
|
||||
*
|
||||
* By returning rejected promises, interceptor functions can cause the
|
||||
* invocation function to fail, regardless of the received reply.
|
||||
*
|
||||
* Interceptors may also modify their message argument in-place to
|
||||
* rewrite received replies before they're processed by the standard
|
||||
* response handling code.
|
||||
*
|
||||
* A common use case for such functions is to detect failing RPC replies
|
||||
* due to expired authentication in order to trigger a new login.
|
||||
*
|
||||
* @callback LuCI.rpc~interceptorFn
|
||||
*
|
||||
* @param {*} msg
|
||||
* The unprocessed, JSON decoded remote RPC method call reply.
|
||||
*
|
||||
* Since interceptors run before the standard parsing logic, the reply
|
||||
* data is not verified for correctness or filtered according to
|
||||
* `expect` and `filter` specifications in the declarations.
|
||||
*
|
||||
* @param {Object} req
|
||||
* The related request object which is an extended variant of the
|
||||
* declaration object, allowing access to internals of the invocation
|
||||
* function such as `filter`, `expect` or `params` values.
|
||||
*
|
||||
* @return {Promise<*>|*}
|
||||
* Interceptor functions may return a promise to defer response
|
||||
* processing until some delayed work completed. Any values the returned
|
||||
* promise resolves to are ignored.
|
||||
*
|
||||
* When the returned promise rejects with an error, the invocation
|
||||
* function will fail too, forwarding the error to the caller.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Registers a new interceptor function.
|
||||
*
|
||||
* @param {LuCI.rpc~interceptorFn} interceptorFn
|
||||
* The inteceptor function to register.
|
||||
*
|
||||
* @returns {LuCI.rpc~interceptorFn}
|
||||
* Returns the given function value.
|
||||
*/
|
||||
addInterceptor: function(interceptorFn) {
|
||||
if (typeof(interceptorFn) == 'function')
|
||||
rpcInterceptorFns.push(interceptorFn);
|
||||
return interceptorFn;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes a registered interceptor function.
|
||||
*
|
||||
* @param {LuCI.rpc~interceptorFn} interceptorFn
|
||||
* The inteceptor function to remove.
|
||||
*
|
||||
* @returns {boolean}
|
||||
* Returns `true` if the given function has been removed or `false`
|
||||
* if it has not been found.
|
||||
*/
|
||||
removeInterceptor: function(interceptorFn) {
|
||||
var oldlen = rpcInterceptorFns.length, i = oldlen;
|
||||
while (i--)
|
||||
|
|
|
@ -1,7 +1,18 @@
|
|||
'use strict';
|
||||
'require rpc';
|
||||
|
||||
return L.Class.extend({
|
||||
/**
|
||||
* @class uci
|
||||
* @memberof LuCI
|
||||
* @hideconstructor
|
||||
* @classdesc
|
||||
*
|
||||
* The `LuCI.uci` class utilizes {@link LuCI.rpc} to declare low level
|
||||
* remote UCI `ubus` procedures and implements a local caching and data
|
||||
* manipulation layer on top to allow for synchroneous operations on
|
||||
* UCI configuration data.
|
||||
*/
|
||||
return L.Class.extend(/** @lends LuCI.uci.prototype */ {
|
||||
__init__: function() {
|
||||
this.state = {
|
||||
newidx: 0,
|
||||
|
@ -22,6 +33,7 @@ return L.Class.extend({
|
|||
expect: { values: { } }
|
||||
}),
|
||||
|
||||
|
||||
callOrder: rpc.declare({
|
||||
object: 'uci',
|
||||
method: 'order',
|
||||
|
@ -58,6 +70,21 @@ return L.Class.extend({
|
|||
method: 'confirm'
|
||||
}),
|
||||
|
||||
|
||||
/**
|
||||
* Generates a new, unique section ID for the given configuration.
|
||||
*
|
||||
* Note that the generated ID is temporary, it will get replaced by an
|
||||
* identifier in the form `cfgXXXXXX` once the configuration is saved
|
||||
* by the remote `ubus` UCI api.
|
||||
*
|
||||
* @param {string} config
|
||||
* The configuration to generate the new section ID for.
|
||||
*
|
||||
* @returns {string}
|
||||
* A newly generated, unique section ID in the form `newXXXXXX`
|
||||
* where `X` denotes a hexadecimal digit.
|
||||
*/
|
||||
createSID: function(conf) {
|
||||
var v = this.state.values,
|
||||
n = this.state.creates,
|
||||
|
@ -70,6 +97,25 @@ return L.Class.extend({
|
|||
return sid;
|
||||
},
|
||||
|
||||
/**
|
||||
* Resolves a given section ID in extended notation to the internal
|
||||
* section ID value.
|
||||
*
|
||||
* @param {string} config
|
||||
* The configuration to resolve the section ID for.
|
||||
*
|
||||
* @param {string} sid
|
||||
* The section ID to resolve. If the ID is in the form `@typename[#]`,
|
||||
* it will get resolved to an internal anonymous ID in the forms
|
||||
* `cfgXXXXXX`/`newXXXXXX` or to the name of a section in case it points
|
||||
* to a named section. When the given ID is not in extended notation,
|
||||
* it will be returned as-is.
|
||||
*
|
||||
* @returns {string|null}
|
||||
* Returns the resolved section ID or the original given ID if it was
|
||||
* not in extended notation. Returns `null` when an extended ID could
|
||||
* not be resolved to existing section ID.
|
||||
*/
|
||||
resolveSID: function(conf, sid) {
|
||||
if (typeof(sid) != 'string')
|
||||
return sid;
|
||||
|
@ -88,6 +134,7 @@ return L.Class.extend({
|
|||
return sid;
|
||||
},
|
||||
|
||||
/* private */
|
||||
reorderSections: function() {
|
||||
var v = this.state.values,
|
||||
n = this.state.creates,
|
||||
|
@ -129,6 +176,7 @@ return L.Class.extend({
|
|||
return Promise.all(tasks);
|
||||
},
|
||||
|
||||
/* private */
|
||||
loadPackage: function(packageName) {
|
||||
if (this.loaded[packageName] == null)
|
||||
return (this.loaded[packageName] = this.callLoad(packageName));
|
||||
|
@ -136,6 +184,24 @@ return L.Class.extend({
|
|||
return Promise.resolve(this.loaded[packageName]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Loads the given UCI configurations from the remote `ubus` api.
|
||||
*
|
||||
* Loaded configurations are cached and only loaded once. Subsequent
|
||||
* load operations of the same configurations will return the cached
|
||||
* data.
|
||||
*
|
||||
* To force reloading a configuration, it has to be unloaded with
|
||||
* {@link LuCI.uci#unload uci.unload()} first.
|
||||
*
|
||||
* @param {string|string[]} config
|
||||
* The name of the configuration or an array of configuration
|
||||
* names to load.
|
||||
*
|
||||
* @returns {Promise<string[]>}
|
||||
* Returns a promise resolving to the names of the configurations
|
||||
* that have been successfully loaded.
|
||||
*/
|
||||
load: function(packages) {
|
||||
var self = this,
|
||||
pkgs = [ ],
|
||||
|
@ -161,6 +227,13 @@ return L.Class.extend({
|
|||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Unloads the given UCI configurations from the local cache.
|
||||
*
|
||||
* @param {string|string[]} config
|
||||
* The name of the configuration or an array of configuration
|
||||
* names to unload.
|
||||
*/
|
||||
unload: function(packages) {
|
||||
if (!Array.isArray(packages))
|
||||
packages = [ packages ];
|
||||
|
@ -175,6 +248,24 @@ return L.Class.extend({
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a new section of the given type to the given configuration,
|
||||
* optionally named according to the given name.
|
||||
*
|
||||
* @param {string} config
|
||||
* The name of the configuration to add the section to.
|
||||
*
|
||||
* @param {string} type
|
||||
* The type of the section to add.
|
||||
*
|
||||
* @param {string} [name]
|
||||
* The name of the section to add. If the name is omitted, an anonymous
|
||||
* section will be added instead.
|
||||
*
|
||||
* @returns {string}
|
||||
* Returns the section ID of the newly added section which is equivalent
|
||||
* to the given name for non-anonymous sections.
|
||||
*/
|
||||
add: function(conf, type, name) {
|
||||
var n = this.state.creates,
|
||||
sid = name || this.createSID(conf);
|
||||
|
@ -193,6 +284,15 @@ return L.Class.extend({
|
|||
return sid;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the section with the given ID from the given configuration.
|
||||
*
|
||||
* @param {string} config
|
||||
* The name of the configuration to remove the section from.
|
||||
*
|
||||
* @param {string} sid
|
||||
* The ID of the section to remove.
|
||||
*/
|
||||
remove: function(conf, sid) {
|
||||
var n = this.state.creates,
|
||||
c = this.state.changes,
|
||||
|
@ -213,6 +313,74 @@ return L.Class.extend({
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* A section object represents the options and their corresponding values
|
||||
* enclosed within a configuration section, as well as some additional
|
||||
* meta data such as sort indexes and internal ID.
|
||||
*
|
||||
* Any internal metadata fields are prefixed with a dot which is isn't
|
||||
* an allowed character for normal option names.
|
||||
*
|
||||
* @typedef {Object<string, boolean|number|string|string[]>} SectionObject
|
||||
* @memberof LuCI.uci
|
||||
*
|
||||
* @property {boolean} .anonymous
|
||||
* The `.anonymous` property specifies whether the configuration is
|
||||
* anonymous (`true`) or named (`false`).
|
||||
*
|
||||
* @property {number} .index
|
||||
* The `.index` property specifes the sort order of the section.
|
||||
*
|
||||
* @property {string} .name
|
||||
* The `.name` property holds the name of the section object. It may be
|
||||
* either an anonymous ID in the form `cfgXXXXXX` or `newXXXXXX` with `X`
|
||||
* being a hexadecimal digit or a string holding the name of the section.
|
||||
*
|
||||
* @property {string} .type
|
||||
* The `.type` property contains the type of the corresponding uci
|
||||
* section.
|
||||
*
|
||||
* @property {string|string[]} *
|
||||
* A section object may contain an arbitrary number of further properties
|
||||
* representing the uci option enclosed in the section.
|
||||
*
|
||||
* All option property names will be in the form `[A-Za-z0-9_]+` and
|
||||
* either contain a string value or an array of strings, in case the
|
||||
* underlying option is an UCI list.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The sections callback is invoked for each section found within
|
||||
* the given configuration and receives the section object and its
|
||||
* associated name as arguments.
|
||||
*
|
||||
* @callback LuCI.uci~sectionsFn
|
||||
*
|
||||
* @param {LuCI.uci.SectionObject} section
|
||||
* The section object.
|
||||
*
|
||||
* @param {string} sid
|
||||
* The name or ID of the section.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Enumerates the sections of the given configuration, optionally
|
||||
* filtered by type.
|
||||
*
|
||||
* @param {string} config
|
||||
* The name of the configuration to enumerate the sections for.
|
||||
*
|
||||
* @param {string} [type]
|
||||
* Enumerate only sections of the given type. If omitted, enumerate
|
||||
* all sections.
|
||||
*
|
||||
* @param {LuCI.uci~sectionsFn} [cb]
|
||||
* An optional callback to invoke for each enumerated section.
|
||||
*
|
||||
* @returns {Array<LuCI.uci.SectionObject>}
|
||||
* Returns a sorted array of the section objects within the given
|
||||
* configuration, filtered by type of a type has been specified.
|
||||
*/
|
||||
sections: function(conf, type, cb) {
|
||||
var sa = [ ],
|
||||
v = this.state.values[conf],
|
||||
|
@ -247,6 +415,31 @@ return L.Class.extend({
|
|||
return sa;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the value of the given option within the specified section
|
||||
* of the given configuration or the entire section object if the
|
||||
* option name is omitted.
|
||||
*
|
||||
* @param {string} config
|
||||
* The name of the configuration to read the value from.
|
||||
*
|
||||
* @param {string} sid
|
||||
* The name or ID of the section to read.
|
||||
*
|
||||
* @param {string} [option]
|
||||
* The option name to read the value from. If the option name is
|
||||
* omitted or `null`, the entire section is returned instead.
|
||||
*
|
||||
* @returns {null|string|string[]|LuCI.uci.SectionObject}
|
||||
* - Returns a string containing the option value in case of a
|
||||
* plain UCI option.
|
||||
* - Returns an array of strings containing the option values in
|
||||
* case of `option` pointing to an UCI list.
|
||||
* - Returns a {@link LuCI.uci.SectionObject section object} if
|
||||
* the `option` argument has been omitted or is `null`.
|
||||
* - Returns `null` if the config, section or option has not been
|
||||
* found or if the corresponding configuration is not loaded.
|
||||
*/
|
||||
get: function(conf, sid, opt) {
|
||||
var v = this.state.values,
|
||||
n = this.state.creates,
|
||||
|
@ -299,6 +492,27 @@ return L.Class.extend({
|
|||
return undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the value of the given option within the specified section
|
||||
* of the given configuration.
|
||||
*
|
||||
* If either config, section or option is null, or if `option` begins
|
||||
* with a dot, the function will do nothing.
|
||||
*
|
||||
* @param {string} config
|
||||
* The name of the configuration to set the option value in.
|
||||
*
|
||||
* @param {string} sid
|
||||
* The name or ID of the section to set the option value in.
|
||||
*
|
||||
* @param {string} option
|
||||
* The option name to set the value for.
|
||||
*
|
||||
* @param {null|string|string[]} value
|
||||
* The option value to set. If the value is `null` or an empty string,
|
||||
* the option will be removed, otherwise it will be set or overwritten
|
||||
* with the given value.
|
||||
*/
|
||||
set: function(conf, sid, opt, val) {
|
||||
var v = this.state.values,
|
||||
n = this.state.creates,
|
||||
|
@ -354,10 +568,53 @@ return L.Class.extend({
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove the given option within the specified section of the given
|
||||
* configuration.
|
||||
*
|
||||
* This function is a convenience wrapper around
|
||||
* `uci.set(config, section, option, null)`.
|
||||
*
|
||||
* @param {string} config
|
||||
* The name of the configuration to remove the option from.
|
||||
*
|
||||
* @param {string} sid
|
||||
* The name or ID of the section to remove the option from.
|
||||
*
|
||||
* @param {string} option
|
||||
* The name of the option to remove.
|
||||
*/
|
||||
unset: function(conf, sid, opt) {
|
||||
return this.set(conf, sid, opt, null);
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the value of the given option or the entire section object of
|
||||
* the first found section of the specified type or the first found
|
||||
* section of the entire configuration if no type is specfied.
|
||||
*
|
||||
* @param {string} config
|
||||
* The name of the configuration to read the value from.
|
||||
*
|
||||
* @param {string} [type]
|
||||
* The type of the first section to find. If it is `null`, the first
|
||||
* section of the entire config is read, otherwise the first section
|
||||
* matching the given type.
|
||||
*
|
||||
* @param {string} [option]
|
||||
* The option name to read the value from. If the option name is
|
||||
* omitted or `null`, the entire section is returned instead.
|
||||
*
|
||||
* @returns {null|string|string[]|LuCI.uci.SectionObject}
|
||||
* - Returns a string containing the option value in case of a
|
||||
* plain UCI option.
|
||||
* - Returns an array of strings containing the option values in
|
||||
* case of `option` pointing to an UCI list.
|
||||
* - Returns a {@link LuCI.uci.SectionObject section object} if
|
||||
* the `option` argument has been omitted or is `null`.
|
||||
* - Returns `null` if the config, section or option has not been
|
||||
* found or if the corresponding configuration is not loaded.
|
||||
*/
|
||||
get_first: function(conf, type, opt) {
|
||||
var sid = null;
|
||||
|
||||
|
@ -369,6 +626,30 @@ return L.Class.extend({
|
|||
return this.get(conf, sid, opt);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the value of the given option within the first found section
|
||||
* of the given configuration matching the specified type or within
|
||||
* the first section of the entire config when no type has is specified.
|
||||
*
|
||||
* If either config, type or option is null, or if `option` begins
|
||||
* with a dot, the function will do nothing.
|
||||
*
|
||||
* @param {string} config
|
||||
* The name of the configuration to set the option value in.
|
||||
*
|
||||
* @param {string} [type]
|
||||
* The type of the first section to find. If it is `null`, the first
|
||||
* section of the entire config is written to, otherwise the first
|
||||
* section matching the given type is used.
|
||||
*
|
||||
* @param {string} option
|
||||
* The option name to set the value for.
|
||||
*
|
||||
* @param {null|string|string[]} value
|
||||
* The option value to set. If the value is `null` or an empty string,
|
||||
* the option will be removed, otherwise it will be set or overwritten
|
||||
* with the given value.
|
||||
*/
|
||||
set_first: function(conf, type, opt, val) {
|
||||
var sid = null;
|
||||
|
||||
|
@ -380,10 +661,60 @@ return L.Class.extend({
|
|||
return this.set(conf, sid, opt, val);
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the given option within the first found section of the given
|
||||
* configuration matching the specified type or within the first section
|
||||
* of the entire config when no type has is specified.
|
||||
*
|
||||
* This function is a convenience wrapper around
|
||||
* `uci.set_first(config, type, option, null)`.
|
||||
*
|
||||
* @param {string} config
|
||||
* The name of the configuration to set the option value in.
|
||||
*
|
||||
* @param {string} [type]
|
||||
* The type of the first section to find. If it is `null`, the first
|
||||
* section of the entire config is written to, otherwise the first
|
||||
* section matching the given type is used.
|
||||
*
|
||||
* @param {string} option
|
||||
* The option name to set the value for.
|
||||
*/
|
||||
unset_first: function(conf, type, opt) {
|
||||
return this.set_first(conf, type, opt, null);
|
||||
},
|
||||
|
||||
/**
|
||||
* Move the first specified section within the given configuration
|
||||
* before or after the second specified section.
|
||||
*
|
||||
* @param {string} config
|
||||
* The configuration to move the section within.
|
||||
*
|
||||
* @param {string} sid1
|
||||
* The ID of the section to move within the configuration.
|
||||
*
|
||||
* @param {string} [sid2]
|
||||
* The ID of the target section for the move operation. If the
|
||||
* `after` argument is `false` or not specified, the section named by
|
||||
* `sid1` will be moved before this target section, if the `after`
|
||||
* argument is `true`, the `sid1` section will be moved after this
|
||||
* section.
|
||||
*
|
||||
* When the `sid2` argument is `null`, the section specified by `sid1`
|
||||
* is moved to the end of the configuration.
|
||||
*
|
||||
* @param {boolean} [after=false]
|
||||
* When `true`, the section `sid1` is moved after the section `sid2`,
|
||||
* when `false`, the section `sid1` is moved before `sid2`.
|
||||
*
|
||||
* If `sid2` is null, then this parameter has no effect and the section
|
||||
* `sid1` is moved to the end of the configuration instead.
|
||||
*
|
||||
* @returns {boolean}
|
||||
* Returns `true` when the section was successfully moved, or `false`
|
||||
* when either the section specified by `sid1` or by `sid2` is not found.
|
||||
*/
|
||||
move: function(conf, sid1, sid2, after) {
|
||||
var sa = this.sections(conf),
|
||||
s1 = null, s2 = null;
|
||||
|
@ -428,6 +759,16 @@ return L.Class.extend({
|
|||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Submits all local configuration changes to the remove `ubus` api,
|
||||
* adds, removes and reorders remote sections as needed and reloads
|
||||
* all loaded configurations to resynchronize the local state with
|
||||
* the remote configuration values.
|
||||
*
|
||||
* @returns {string[]}
|
||||
* Returns a promise resolving to an array of configuration names which
|
||||
* have been reloaded by the save operation.
|
||||
*/
|
||||
save: function() {
|
||||
var v = this.state.values,
|
||||
n = this.state.creates,
|
||||
|
@ -503,6 +844,17 @@ return L.Class.extend({
|
|||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Instructs the remote `ubus` UCI api to commit all saved changes with
|
||||
* rollback protection and attempts to confirm the pending commit
|
||||
* operation to cancel the rollback timer.
|
||||
*
|
||||
* @param {number} [timeout=10]
|
||||
* Override the confirmation timeout after which a rollback is triggered.
|
||||
*
|
||||
* @returns {Promise<number>}
|
||||
* Returns a promise resolving/rejecting with the `ubus` RPC status code.
|
||||
*/
|
||||
apply: function(timeout) {
|
||||
var self = this,
|
||||
date = new Date();
|
||||
|
@ -532,6 +884,57 @@ return L.Class.extend({
|
|||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* An UCI change record is a plain array containing the change operation
|
||||
* name as first element, the affected section ID as second argument
|
||||
* and an optional third and fourth argument whose meanings depend on
|
||||
* the operation.
|
||||
*
|
||||
* @typedef {string[]} ChangeRecord
|
||||
* @memberof LuCI.uci
|
||||
*
|
||||
* @property {string} 0
|
||||
* The operation name - may be one of `add`, `set`, `remove`, `order`,
|
||||
* `list-add`, `list-del` or `rename`.
|
||||
*
|
||||
* @property {string} 1
|
||||
* The section ID targeted by the operation.
|
||||
*
|
||||
* @property {string} 2
|
||||
* The meaning of the third element depends on the operation.
|
||||
* - For `add` it is type of the section that has been added
|
||||
* - For `set` it either is the option name if a fourth element exists,
|
||||
* or the type of a named section which has been added when the change
|
||||
* entry only contains three elements.
|
||||
* - For `remove` it contains the name of the option that has been
|
||||
* removed.
|
||||
* - For `order` it specifies the new sort index of the section.
|
||||
* - For `list-add` it contains the name of the list option a new value
|
||||
* has been added to.
|
||||
* - For `list-del` it contains the name of the list option a value has
|
||||
* been removed from.
|
||||
* - For `rename` it contains the name of the option that has been
|
||||
* renamed if a fourth element exists, else it contains the new name
|
||||
* a section has been renamed to if the change entry only contains
|
||||
* three elements.
|
||||
*
|
||||
* @property {string} 4
|
||||
* The meaning of the fourth element depends on the operation.
|
||||
* - For `set` it is the value an option has been set to.
|
||||
* - For `list-add` it is the new value that has been added to a
|
||||
* list option.
|
||||
* - For `rename` it is the new name of an option that has been
|
||||
* renamed.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fetches uncommitted UCI changes from the remote `ubus` RPC api.
|
||||
*
|
||||
* @method
|
||||
* @returns {Promise<Object<string, Array<LuCI.uci.ChangeRecord>>>}
|
||||
* Returns a promise resolving to an object containing the configuration
|
||||
* names as keys and arrays of related change records as values.
|
||||
*/
|
||||
changes: rpc.declare({
|
||||
object: 'uci',
|
||||
method: 'changes',
|
||||
|
|
Loading…
Reference in a new issue