doc(variable): document variable
This commit is contained in:
parent
4039e01769
commit
c72b34cbf9
2 changed files with 262 additions and 166 deletions
|
|
@ -24,42 +24,6 @@ It is with its name that we will be able to interact with the family.
|
||||||
|
|
||||||
Have a look at the :ref:`family naming convention <namingconvention>`
|
Have a look at the :ref:`family naming convention <namingconvention>`
|
||||||
|
|
||||||
Shorthand declaration
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
Shorthand declaration is a way to declare a family in a single line.
|
|
||||||
|
|
||||||
To create a family, just add a key with it's name and variables as values.
|
|
||||||
|
|
||||||
Here is a simple example:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
%YAML 1.2
|
|
||||||
---
|
|
||||||
version: 1.1
|
|
||||||
my_family:
|
|
||||||
|
|
||||||
variable:
|
|
||||||
...
|
|
||||||
|
|
||||||
By default, the description of the variable is the family name.
|
|
||||||
It's a best practice to description a family. Just add comment in same line of name, this comment is use as description.
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
%YAML 1.2
|
|
||||||
---
|
|
||||||
version: 1.1
|
|
||||||
my_family: # This is a great family
|
|
||||||
|
|
||||||
variable:
|
|
||||||
...
|
|
||||||
|
|
||||||
But in shorthand notation, you can only define family name and description.
|
|
||||||
|
|
||||||
.. attention:: Any other parameters will be considered as a variable. Do not use shorthand in this case.
|
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
|
@ -166,6 +130,40 @@ Parameters
|
||||||
If a subfamily or a subvariable already has the name of a parameter it is possible to use the "_<parameter>" name.
|
If a subfamily or a subvariable already has the name of a parameter it is possible to use the "_<parameter>" name.
|
||||||
You can have a look at the tutorial with a real world sample :doc:`of parameter with "_" <tutorial/underscore_parameter>`.
|
You can have a look at the tutorial with a real world sample :doc:`of parameter with "_" <tutorial/underscore_parameter>`.
|
||||||
|
|
||||||
|
Shorthand declaration
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Shorthand declaration is a way to declare a family in a single line.
|
||||||
|
|
||||||
|
To create a family, just add a key with it's name and variables as values:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
version: 1.1
|
||||||
|
my_family:
|
||||||
|
|
||||||
|
my_variable:
|
||||||
|
...
|
||||||
|
|
||||||
|
By default, the description of the family is the family name.
|
||||||
|
It's a best practice to description a family. Just add comment in same line of name, this comment is use as description:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
version: 1.1
|
||||||
|
my_family: # This is a great family
|
||||||
|
|
||||||
|
my_variable:
|
||||||
|
...
|
||||||
|
|
||||||
|
But in shorthand notation, you can only define family name and description.
|
||||||
|
|
||||||
|
.. attention:: Any other parameters will be considered as a variable. Do not use shorthand in this case.
|
||||||
|
|
||||||
A family
|
A family
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
|
@ -180,7 +178,7 @@ Here is a simple example:
|
||||||
description: This is a great family
|
description: This is a great family
|
||||||
help: This family is great because we have great variables inside
|
help: This family is great because we have great variables inside
|
||||||
|
|
||||||
variable:
|
my_variable:
|
||||||
...
|
...
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ Synopsis
|
||||||
|
|
||||||
variable
|
variable
|
||||||
|
|
||||||
A variable is an abstract black box (container) paired with an associated symbolic name, most often an option configuration, hich contains some defined or undefined data setting referred to as a :term:`value`.
|
A variable is an abstract black box (container) paired with an associated symbolic name, most often an option configuration, which contains some defined or undefined data setting referred to as a :term:`value`.
|
||||||
|
|
||||||
value
|
value
|
||||||
|
|
||||||
|
|
@ -29,97 +29,15 @@ Synopsis
|
||||||
Names
|
Names
|
||||||
------
|
------
|
||||||
|
|
||||||
Variable name
|
It is with its name that we will be able to interact with the variable.
|
||||||
|
|
||||||
Variable's associated symbolic name.
|
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
Have a look at the :ref:`convention on variable naming link <namingconvention>`.
|
Have a look at the :ref:`variable naming convention <namingconvention>`
|
||||||
|
|
||||||
Variable's types
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
.. type-along:: type inference
|
|
||||||
|
|
||||||
If the `type` parameter is not set, Rougail infers a `string` type for the `proxy_mode` configuration option variable type as defined in the structure file.
|
|
||||||
|
|
||||||
.. type-along:: integer type
|
|
||||||
|
|
||||||
If the operator sets an option value for example with the `integer` type, like this:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
---
|
|
||||||
example_var:
|
|
||||||
description: This is an example variable
|
|
||||||
type: integer
|
|
||||||
|
|
||||||
Then Rougail will expect a `int` as a value for the `example_var` variable.
|
|
||||||
|
|
||||||
.. type-along:: the choice type
|
|
||||||
|
|
||||||
.. glossary::
|
|
||||||
|
|
||||||
choice type
|
|
||||||
|
|
||||||
A choice type variable is a variable where the content is constrained by a list
|
|
||||||
|
|
||||||
When a variable's setting is "choice" (`type: choice`), it means that
|
|
||||||
there is a list of available values that can be selected.
|
|
||||||
|
|
||||||
Shorthand declaration
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
Shorthand declaration is a way to declare a variable in a single line. But you can only define variable name, description, multi or default value.
|
|
||||||
|
|
||||||
.. glossary::
|
|
||||||
|
|
||||||
short-hand notation
|
|
||||||
|
|
||||||
A short-hand notation in Rougail is the ability to define a variable in
|
|
||||||
a short-hand way, there are several example:
|
|
||||||
|
|
||||||
- a default value:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
my_var: true
|
|
||||||
|
|
||||||
instead of:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
my_var:
|
|
||||||
default: true
|
|
||||||
|
|
||||||
To create a variable, just add a key with it's name and default value as value.
|
|
||||||
Be careful not to declare any other parameters.
|
|
||||||
|
|
||||||
To declare a multi variable just add a list as default value.
|
|
||||||
|
|
||||||
By default, the description of the variable is the variable name.
|
|
||||||
If you add a comment in the same line of the name, this comment will be used has a description.
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
%YAML 1.2
|
|
||||||
---
|
|
||||||
version: 1.1
|
|
||||||
|
|
||||||
my_variable: 1 # This is a great integer variable
|
|
||||||
|
|
||||||
my_multi_variable: # This is a great multi string variable
|
|
||||||
- value1
|
|
||||||
- value2
|
|
||||||
...
|
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. list-table::
|
.. list-table::
|
||||||
:widths: 15 45
|
:widths: 15 45
|
||||||
:header-rows: 1
|
:header-rows: 1
|
||||||
|
|
@ -354,12 +272,107 @@ Parameters
|
||||||
|
|
||||||
**Default value**: `null`
|
**Default value**: `null`
|
||||||
|
|
||||||
Variables type list
|
* - **choices**
|
||||||
--------------------
|
|
||||||
|
:term:`calculation` or a list of :term:`calculation` or data
|
||||||
|
- Available choices.
|
||||||
|
|
||||||
|
.. important:: This parameter is only available for variable with `choice` type.
|
||||||
|
|
||||||
|
* - **regexp**
|
||||||
|
|
||||||
|
`string`
|
||||||
|
- Validation with a regular expressions.
|
||||||
|
|
||||||
|
.. important:: This parameter is only available for variable with `regexp` type.
|
||||||
|
|
||||||
|
Shorthand declaration
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Shorthand declaration is a way to declare a variable in a condenced number of line.
|
||||||
|
|
||||||
|
To create a variable, just add a key with it's name:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
version: 1.1
|
||||||
|
|
||||||
|
my_variable:
|
||||||
|
...
|
||||||
|
|
||||||
|
You can add a default value:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
version: 1.1
|
||||||
|
|
||||||
|
my_variable: my_value
|
||||||
|
...
|
||||||
|
|
||||||
|
Or a multi default value:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
version: 1.1
|
||||||
|
|
||||||
|
my_variable:
|
||||||
|
- my_value_1
|
||||||
|
- my_value_2
|
||||||
|
...
|
||||||
|
|
||||||
|
By default, the description of the variable is the variable name.
|
||||||
|
It's a best practice to description a variable. Just add comment in same line of name, this comment is use as description:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
version: 1.1
|
||||||
|
|
||||||
|
my_variable: my_value # This is a great variable
|
||||||
|
...
|
||||||
|
|
||||||
|
But in shorthand notation, you can only define variable name, default value, multi and description.
|
||||||
|
|
||||||
|
.. attention:: Any other parameters will create extra variables or families
|
||||||
|
|
||||||
|
..
|
||||||
|
.. .. glossary::
|
||||||
|
..
|
||||||
|
.. short-hand notation
|
||||||
|
..
|
||||||
|
.. A short-hand notation in Rougail is the ability to define a variable in
|
||||||
|
.. a short-hand way, there are several example:
|
||||||
|
..
|
||||||
|
.. - a default value:
|
||||||
|
..
|
||||||
|
.. .. code-block:: yaml
|
||||||
|
..
|
||||||
|
.. my_var: true
|
||||||
|
..
|
||||||
|
.. instead of:
|
||||||
|
..
|
||||||
|
.. .. code-block:: yaml
|
||||||
|
..
|
||||||
|
.. my_var:
|
||||||
|
.. default: true
|
||||||
|
|
||||||
|
|
||||||
|
Variable's types
|
||||||
|
-----------------
|
||||||
|
|
||||||
A variable **always has a type**. The system is **strongly** typed.
|
A variable **always has a type**. The system is **strongly** typed.
|
||||||
|
|
||||||
Depending on the definition of the variable type, the defined variable will accept values of the associated type.
|
Depending on the definition of the variable type, the defined variable will accept values of the associated type.
|
||||||
|
|
||||||
|
Primitive Types
|
||||||
|
'''''''''''''''''''
|
||||||
|
|
||||||
.. list-table::
|
.. list-table::
|
||||||
:widths: 15 25 20 15
|
:widths: 15 25 20 15
|
||||||
|
|
@ -373,123 +386,208 @@ Depending on the definition of the variable type, the defined variable will acce
|
||||||
* - string
|
* - string
|
||||||
- character string (default type)
|
- character string (default type)
|
||||||
-
|
-
|
||||||
- test
|
- example
|
||||||
|
|
||||||
"1"
|
"1"
|
||||||
|
|
||||||
"true"
|
"true"
|
||||||
|
|
||||||
* - integer
|
* - integer
|
||||||
- a integer
|
- a integer
|
||||||
- `min_integer`: minimum integer allowed
|
- `min_integer`: minimum integer allowed (unlimited by default)
|
||||||
|
|
||||||
|
`max_integer`: maximum integer allowed (unlimited by default)
|
||||||
|
- 42
|
||||||
|
|
||||||
`max_integer`: maximum integer allowed
|
|
||||||
- 1
|
|
||||||
* - float
|
* - float
|
||||||
- a floating number
|
- a floating number
|
||||||
-
|
-
|
||||||
- 1.2
|
- 1.42
|
||||||
|
|
||||||
* - boolean
|
* - boolean
|
||||||
- A boolean, if no value is defined the default value of this variable will be `true`, the variable will also be :term:`mandatory` by default
|
- A boolean, if no value is defined the default value of this variable will be `true`, the variable will also be :term:`mandatory` by default
|
||||||
|
|
||||||
|
.. seealso:: tutorial with a real world sample :doc:`boolean type variable <tutorial/types>`
|
||||||
-
|
-
|
||||||
- `true`
|
- `true`
|
||||||
|
|
||||||
`false`
|
`false`
|
||||||
|
|
||||||
|
Specialized type
|
||||||
|
''''''''''''''''''
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:widths: 15 25 20 15
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
* - Value
|
||||||
|
- Comments
|
||||||
|
- Parameters
|
||||||
|
- Samples
|
||||||
|
|
||||||
* - secret
|
* - secret
|
||||||
- a secret (like a password, a private key, etc.)
|
- a secret (like a password, a private key, etc.)
|
||||||
-
|
|
||||||
|
.. seealso:: tutorial with a real world sample :doc:`secret type variable <tutorial/redefine>`
|
||||||
|
- `min_len`: minimum characters length for the secret (unlimited by default)
|
||||||
|
|
||||||
|
`max_len`: maximum characters length for the secret (unlimited by default)
|
||||||
|
|
||||||
|
`forbidden_char`: forbidden characters (no character default)
|
||||||
- `hO_'hi`
|
- `hO_'hi`
|
||||||
|
|
||||||
* - mail
|
* - mail
|
||||||
- a mail address
|
- a mail address
|
||||||
-
|
-
|
||||||
- test@rougail.example
|
- test@rougail.example
|
||||||
|
|
||||||
* - unix_filename
|
* - unix_filename
|
||||||
- a file name in the Unix meaning
|
- a file name in the Unix meaning
|
||||||
-
|
- `allow_relative`: this filename could be a relative path (`false` by default)
|
||||||
|
|
||||||
|
`test_existence`: this file must exist (`false` by default)
|
||||||
|
|
||||||
|
`types`: "file type allowed ("file", "directory")
|
||||||
- :file:`/etc/passwd`
|
- :file:`/etc/passwd`
|
||||||
|
|
||||||
* - date
|
* - date
|
||||||
- a date in the format `%Y-%m-%d`
|
- a date in the format `%Y-%m-%d`
|
||||||
-
|
-
|
||||||
- `2021-01-30`
|
- `2021-01-30`
|
||||||
|
|
||||||
* - unix_user
|
* - unix_user
|
||||||
- a user in the Unix meaning
|
- a user in the Unix meaning
|
||||||
|
|
||||||
|
.. seealso:: tutorial with a real world sample :doc:`unix type variable <tutorial/redefine>`
|
||||||
-
|
-
|
||||||
- test
|
- test
|
||||||
|
|
||||||
* - ip
|
* - ip
|
||||||
- any kind of IPv4 address
|
- any kind of IPv4 address
|
||||||
- `private_only`: only private IPs (`false` by default)
|
- `private_only`: only private IPs (`false` by default)
|
||||||
|
|
||||||
`allow_reserved`: allows reserved IPs (`true` by default)
|
`allow_reserved`: allows reserved IPs (`true` by default)
|
||||||
- `1.2.3.4`
|
|
||||||
* - cidr
|
|
||||||
- any IPv4 address in the CIDR format
|
|
||||||
- `private_only`: only private IPs (`false` by default)
|
|
||||||
|
|
||||||
`allow_reserved`: allows reserved IPs (`false` by default)
|
`cidr`: IP must be in CIDR format (`false` by default)
|
||||||
- `1.2.3.4/24`
|
- `1.2.3.4`
|
||||||
|
|
||||||
* - netmask
|
* - netmask
|
||||||
- mask of an IPv4 address
|
- mask of an IPv4 address
|
||||||
-
|
-
|
||||||
- `255.255.255.0`
|
- `255.255.255.0`
|
||||||
|
|
||||||
* - network
|
* - network
|
||||||
- network address
|
- network address
|
||||||
-
|
- `cidr`: network must be in CIDR format (`false` by default)
|
||||||
|
|
||||||
|
`private_only`: private network are allowed (`false` by default)
|
||||||
|
|
||||||
|
`allow_reserved`: reserved network are allowed (`false` by default)
|
||||||
- `192.168.1.0`
|
- `192.168.1.0`
|
||||||
* - network_cidr
|
|
||||||
- network address in CIDR format
|
|
||||||
-
|
|
||||||
- `192.168.1.0/24`
|
|
||||||
* - broadcast
|
* - broadcast
|
||||||
- broadcast address
|
- broadcast address
|
||||||
-
|
-
|
||||||
- `255.255.255.255`
|
- `1.1.1.255`
|
||||||
* - netbios
|
|
||||||
- netbios name
|
|
||||||
-
|
|
||||||
- machine
|
|
||||||
* - domainname
|
* - domainname
|
||||||
- domain name
|
- domain name
|
||||||
- `allow_ip`: allows an IP rather than a domain name (`false` by default)
|
- `type`: type of domain name (`domainname` (by default), `netbios`, `hostname`)
|
||||||
|
|
||||||
`allow_cidr_network`: allows a CIDR type network address (`false` by default)
|
`allow_ip`: the domain name can be an IP (`false` by default)
|
||||||
|
|
||||||
`allow_without_dot`: allows names without a dot (`false` by default)
|
`allow_cidr_network`: the domain name can be network in CIDR format (`false` by default)
|
||||||
|
|
||||||
`allow_startswith_dot`: allows starting with a point (`false` by default)
|
`allow_without_dot`: the domain name can be a hostname (`false` by default)
|
||||||
|
|
||||||
|
`allow_startswith_dot`: the domain name can starts by a dot (`false` by default)
|
||||||
|
|
||||||
|
`test_existence`: the domain name must exist (`false` by default)
|
||||||
|
|
||||||
|
.. seealso:: tutorial with a real world sample :doc:`domainname type variable <tutorial/types>` or :doc:`a more complet domainname type variable <tutorial/multiple>`
|
||||||
- `rougail.example`
|
- `rougail.example`
|
||||||
* - hostname
|
|
||||||
- host name
|
|
||||||
- `allow_ip`: allows an IP rather than a domain name (`false` by default)
|
|
||||||
- machine
|
|
||||||
* - web_address
|
* - web_address
|
||||||
- web address
|
- web address
|
||||||
- `allow_ip`: allows an IP rather than a domain name (`false` by default)
|
- `type`: type of domain name (`domainname` (by default), `netbios`, `hostname`)
|
||||||
|
|
||||||
`allow_without_dot`: allows names without a dot (`true` by default)
|
`allow_ip`: the domain name can be an IP (`false` by default)
|
||||||
|
|
||||||
|
`allow_cidr_network`: the domain name can be network in CIDR format (`false` by default)
|
||||||
|
|
||||||
|
`allow_without_dot`: the domain name can be a hostname (`false` by default)
|
||||||
|
|
||||||
|
`allow_startswith_dot`: the domain name can starts by a dot (`false` by default)
|
||||||
|
|
||||||
|
`test_existence`: the domain name must exist (`false` by default)
|
||||||
|
|
||||||
|
- `allow_range`: can be range of port, for example 80:85 (`false` by default)
|
||||||
|
|
||||||
|
`allow_zero`: port 0 is allowed (false by default)
|
||||||
|
|
||||||
|
`allow_wellknown`: well-known ports (1 to 1023) are allowed (`true` by default)
|
||||||
|
|
||||||
|
`allow_registred`: registred ports (1024 to 49151) are allowed (`true` by default)
|
||||||
|
|
||||||
|
`allow_private`: private ports (greater than 49152) are allowed (`false` by default)
|
||||||
|
|
||||||
|
.. seealso:: tutorial with a real world sample :doc:`web_address type variable <tutorial/webaddress>`
|
||||||
- http://rougail.example
|
- http://rougail.example
|
||||||
|
|
||||||
* - port
|
* - port
|
||||||
- port
|
- port
|
||||||
- `allow_range`: allows a port range, for example 80:85 (`false` by default)
|
- `allow_range`: can be range of port, for example 80:85 (`false` by default)
|
||||||
|
|
||||||
`allow_zero`: allows port 0 (false by default)
|
`allow_zero`: port 0 is allowed (false by default)
|
||||||
|
|
||||||
`allow_wellknown`: allows ports from 1 to 1023 (`true` by default)
|
`allow_wellknown`: well-known ports (1 to 1023) are allowed (`true` by default)
|
||||||
|
|
||||||
`allow_registred`: allows ports from 1024 to 49151 (`true` by default)
|
`allow_registred`: registred ports (1024 to 49151) are allowed (`true` by default)
|
||||||
|
|
||||||
`allow_private`: allows ports greater than 49152 (`true` by default)
|
`allow_private`: private ports (greater than 49152) are allowed (`false` by default)
|
||||||
|
|
||||||
`allow_protocol`: allows the addition of the protocol, for example tcp:80 (`false` by default)
|
|
||||||
|
|
||||||
|
.. seealso:: tutorial with a real world sample :doc:`port type variable <tutorial/types>`
|
||||||
- 8080
|
- 8080
|
||||||
|
|
||||||
* - mac
|
* - mac
|
||||||
- MAC address
|
- MAC address
|
||||||
-
|
-
|
||||||
- 11:11:11:11:11:11
|
- 11:11:11:11:11:11
|
||||||
|
|
||||||
* - unix_permissions
|
* - unix_permissions
|
||||||
- access rights to the file, directory, etc.
|
- access rights to the file, directory, etc.
|
||||||
-
|
-
|
||||||
- 644
|
- 644
|
||||||
|
|
||||||
* - choice
|
* - choice
|
||||||
- choice variable
|
- available choices
|
||||||
|
|
||||||
|
.. seealso:: tutorial with a real world sample :doc:`choice type variable <tutorial/choice>`
|
||||||
-
|
-
|
||||||
-
|
-
|
||||||
|
|
||||||
|
* - regexp
|
||||||
|
- Validation with a regular expressions
|
||||||
|
|
||||||
|
.. seealso:: tutorial with a real world sample :doc:`regexp type variable <tutorial/regexp>`
|
||||||
|
-
|
||||||
|
- r"^#(?:[0-9a-f]{3}){1,2}$"
|
||||||
|
|
||||||
|
Default type
|
||||||
|
''''''''''''''
|
||||||
|
|
||||||
|
If the `type` parameter is not set, Rougail has to define a logical type to valid correctly values:
|
||||||
|
|
||||||
|
- if `choices` or `regexp` parameter is set, Rougail will set the `choice` or `regexp` type
|
||||||
|
|
||||||
|
.. seealso:: tutorial with a real world sample :doc:`choice deducted type <tutorial/choice>` or :doc:`regexp deducted type <tutorial/regexp>`
|
||||||
|
|
||||||
|
- if a default value is define, Rougail will infers default value type and set a primitive type to the variable
|
||||||
|
|
||||||
|
.. seealso:: tutorial with a real world sample :doc:`type inference <tutorial/types>`
|
||||||
|
|
||||||
|
- if a variable calculation is define as default value, Rougail copy the type
|
||||||
|
|
||||||
|
.. seealso:: tutorial with a real world sample :doc:`type copying <tutorial/calculated>`
|
||||||
|
|
||||||
|
- the default type is `string`
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue