Slots

Magic creates the following dynamic slots during startup. Notice, most of these slots are there exclusively to make sure the middleware of Magic works correctly, and are not intended to be used directly by you in your own Hyperlambda code, unless explicitly stated otherwise, and/or you’re extending Magic, or replacing parts of its core with your own custom logic.

  • [magic.auth.authenticate] - Authenticates a user and returns a JWT token
  • [magic.auth.change-password] - Allows a user to reset his or her password
  • [magic.auth.create-user] - Creates a new user in Magic
  • [magic.auth.ensure-role] - Ensures the specified role exists, and if not, creates it
  • [magic.db.mysql.databases] - Returns all databases for a specified connection string
  • [magic.db.mysql.tables] - Returns all tables for the specified connection-string/database combination
  • [magic.db.mysql.columns] - Returns all columns for a specified connection-string/database/table combination
  • [magic.db.mysql.foreign_keys] - Returns all foreign keys for a specified connection-string/database/table combination
  • [magic.db.mysql.indexes] - Returns all indexes for the specified connection-string/database/table combination
  • [magic.db.mssql.databases] - See the MySQL equivalent above
  • [magic.db.mssql.tables] - See the MySQL equivalent above
  • [magic.db.mssql.columns] - See the MySQL equivalent above
  • [magic.db.mssql.foreign_keys] - See the MySQL equivalent above
  • [magic.db.mssql.indexes] - Returns all indexes for the specified connection-string/database/table combination
  • [magic.db.pgsql.databases] - See the MySQL equivalent above
  • [magic.db.pgsql.tables] - See the MySQL equivalent above
  • [magic.db.pgsql.columns] - See the MySQL equivalent above
  • [magic.db.pgsql.foreign_keys] - See the MySQL equivalent above
  • [magic.db.pgsql.indexes] - Returns all indexes for the specified connection-string/database/table combination
  • [magic.db.sqlite.databases] - See the MySQL equivalent above
  • [magic.db.sqlite.tables] - See the MySQL equivalent above
  • [magic.db.sqlite.columns] - See the MySQL equivalent above
  • [magic.db.sqlite.foreign_keys] - See the MySQL equivalent above
  • [magic.db.sqlite.indexes] - Returns all indexes for the specified connection-string/database/table combination
  • [magic.emails.send] - Sends a “braided” email
  • [magic.io.file.load-recursively] - Loads all files from within some folder recursively
  • [magic.modules.ensure-database] - Ensures some database exists by executing its create database SQL file
  • [magic.modules.install-module] - Installs a module in your system
  • [transformers.hash-password] - Hashes a specified password in place

These are slots related to authentication and authorisation, and allows you to authenticate, change password of users, and other things related to the “auth” parts of the system. Notice, you would rarely if ever use these slots directly, since the system contains several endpoints helping you out with the consumption of these slots. However, to be complete, we’ve chosen to document these none the less.

[magic.auth.authenticate]

This slot authenticates a user towards your specific authentication and authorisation logic, which implies looking up the username in the magic.users database table, and ensuring the password is correct. If both the username exists, and the password is correct, the slot will return a valid JWT token, allowing you to use it as a token authorising you to act on behalf of the user, and/or return the JWT token to the client. Below is an example assuming your root password is “admin”. Try to execute the following code with your own root user’s password to see how it works.

signal:magic.auth.authenticate
   username:root
   password:admin

The above would return something resembling the following.

signal
   ticket:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxx

[magic.auth.change-password]

Allows a user to change his or her password. This slot requires the user to be already authenticated and having a valid JWT token. An example of changing your own password to “admin2” can be found below.

signal:magic.auth.change-password
   password:admin2

If you invoke the above Hyperlambda, and log out from Magic, you’ll need to use “admin2” as your password to authenticate again. Notice, this slot will evaluate within the context of the “current user”, implying the only person who can change his or her password is the user currently being authenticated.

Yet again, Magic contains helper endpoints for these types of operations, and you would probably never want to directly invoke the slots yourself, but rather use the helper endpoints from your own frontend if you wish to use this type of functionality. See the endpoints section for details.

[magic.auth.create-user]

This slot allows you to create a new user in Magic, with the specified username/password combination, belonging to the specified role(s). Below is an example of usage.

signal:magic.auth.create-user
   username:foo
   password:bar
   roles
      .:guest

The above creates a new user called “foo” with the password of “bar” belonging to the “guest” role. If you execute the above Hyperlambda for then to go to your Users & Roles component item, you will find this user. Notice, you might want to delete the user after having verified it exists.

[magic.auth.ensure-role]

This slot allows you to ensure that the specified role exists, and if not, create it. This is a useful slot when you create your own Hyperlambda modules, and your module depends upon some role existing in the system. Typically you’d invoke this slot from one of your module’s startup files, since these are executed both during startup and during installation of your module. Below is an example of usage.

signal:magic.auth.ensure-role
   role:foo-role
   description:This is the foo role

If you execute the above Hyperlambda and go to USers & Roles afterwards, you will see how you now have a “foo-role” in your system.

Database meta traversal

All the following slots are a part of the database meta system, and allows you to retrieve meta data about your databases, such as database names, table names, columns names, and foreign keys for tables. These slots are heavily relied upon by the CRUDifier, as it creates a Hyperlambda backend for you, in order to determine which arguments your HTTP endpoints requires, and how to validate these during HTTP invocations towards your backend.

All these have at least 4 versions, one for SQLite, one for MySQL, one for PostgreSQL, and a fourth for SQL Server, and their only difference is that the MySQL versions use “mysql” as its slot name, SQL Server uses “mssql”, PostgreSQL uses “pgsql” and SQLite uses “sqlite”. Besides from this, they’re identical in regards to their APIs, which is the point, since it allows for these slots to be used transparently, or “polymorphistically” towards any underlaying database type. In the following section, we therefor document their MySQL version, implying you’ll have to exchange the “mysql” parts to test these towards a different database type.

[magic.db.mysql.databases]

This slot returns all databases the system has access to within the specified connection string. Example usage can be found below.

signal:magic.db.mysql.databases
   connection-string:generic

The above would result in a list of databases resembling the following.

signal
   ""
      db:information_schema
   ""
      db:magic
   ""
      db:mysql
   ""
      db:performance_schema
   ""
      db:sys

[magic.db.mysql.tables]

This slot returns all tables for the specified [connection-string]/[database] combination. Below is example usage.

signal:magic.db.mysql.tables
   connection-string:generic
   database:magic

The above would return all tables in your “magic” database, resulting in something resembling the following.

signal
   ""
      table:crypto_invocations
   ""
      table:crypto_keys
   ""
      table:log_entries
   ""
      table:magic_version
   ""
      table:roles
   ""
      table:task_due
   ""
      table:tasks
   ""
      table:users
   ""
      table:users_crypto_keys
   ""
      table:users_roles

[magic.db.mysql.columns]

This slot returns all columns for the specified [connection-string]/[database]/[table] combination. Below is example usage.

signal:magic.db.mysql.columns
   connection-string:generic
   database:magic
   table:users_roles

The above would return all columns in your “users_roles” table, resulting in something resembling the following.

signal
   ""
      name:role
      db:varchar(45)
      nullable:bool:false
      primary:bool:true
      automatic:bool:false
      hl:string
   ""
      name:user
      db:varchar(256)
      nullable:bool:false
      primary:bool:true
      automatic:bool:false
      hl:string

The fields implies the following.

  • [name] - Name of column
  • [db] - Database type for column
  • [nullable] - If true column accepts null values
  • [primary] - If true column is a part of the primary key for the table
  • [automatic] - If true column has a default value
  • [hl] - Hyperlambda type mapping for the column

[magic.db.mysql.foreign_keys]

This slot returns all foreign keys for the specified [connection-string]/[database]/[table] combination. Below is example usage.

signal:magic.db.mysql.foreign_keys
   connection-string:generic
   database:magic
   table:users_roles

The above would return all foreign keys in your “users_roles” table, resulting in something resembling the following.

signal
   ""
      column:role
      foreign_table:roles
      foreign_column:name
   ""
      column:user
      foreign_table:users
      foreign_column:username

In the above result we can see how the “role” column in the “users_roles” table for instance has a foreign key declaration pointing towards the “name” column in the “roles” table, and similarly for the “user” column pointing towards the “users” table’s “username” column. The resulting values implies the following.

  • [column] - Name of column in table you’re querying
  • [foreign_table] - Name of table the column is referencing
  • [foreign_column] - Name of column in foreign table the column is referencing

[magic.db.mysql.indexes]

This slot returns all indexes for the specified [connection-string]/[database]/[table] combination. Below is example usage.

signal:magic.db.mysql.indexes
   connection-string:generic
   database:magic
   table:users_roles

The above would return all indexes in your “users_roles” table.

Misc slots

These are slots that don’t belong to a specific category solving some problem related to your applications.

[magic.io.file.load-recursively]

This slot loads all files recursively within the specified folder, and returns their filenames and their content. The following example Hyperlambda illustrates its usage.

signal:magic.io.file.load-recursively
   .:/modules/

The above will result in something resembling the following. Notice, the result below has been significantly snippet.

signal
   :/modules/README.md
      :"\n# Your modules folder\n\nThis ... snip ...\n"
   :/modules/magic/crypto_invocations-count.get.hl
      :@"..."

As you can see above the result is an array of filenames, where each filename has one child node, being the actual content of the file. The slot is used when for instance a frontend application is being generated based upon a template - In addition when you download a folder or something similar.

[magic.modules.ensure-database]

This slot ensures that a module’s database exists by invoking its associated create database SQL file. The slot requires the following arguments.

  • [module] - Name of module
  • [database] - Name of database to check for

The slot basically checks to see if the specified [database] database exists, and if not, attempts to find its associated “xxx.yyy.sql” script within its folder, where “xxx” is the module name and “yyy” is the default database type. The slot will also automatically execute any migration scripts associated with the module. Notice, the “Ensure database” macro in “Hyper IDE” automatically takes care of wiring up invocations to this slot, creating the required structure in the process.

[magic.modules.install-module]

This slot installs a module that has been previously unzipped into your modules folder by making sure all startup files are executed. Typically you wouldn’t want to execute this directly yourself, but rely upon Magic’s middleware to invoke the slot. If you unzip a zip file inside of your “modules” folder, and/or download a bazar item, this slot will be automatically invoked.

[transformers.hash-password]

This slot is a “transformer” and typically used for input payloads originating from HTTP invocations, such as when creating a new user, etc. The following Hyperlambda illustrates its usage.

.arguments
   password:foo
eval:x:+
signal:transformers.hash-password
   reference:x:@.arguments/*/password

The idea of the slot is that it transforms in place the specified argument by reference. Implying executing the above Hyperlambda will result in something resembling the following.

.arguments
   password:$2b$10$ZjOhP3DecbgqYsTKknvLmODs1H1C6bfCheBug6iTk5TNmEckE9H3e

This makes it perfect for “transforming” input payloads containing passwords before persisting these into your database.