No vars found in this namespace.
symbolic names for attribute options, so you can use these instead of keywords so that doc strings work.
symbolic names for attribute options, so you can use these instead of keywords so that doc strings work.
Authentication and Authorization Support.
WARNING: This part of RAD will not be standardized for some time. You will need to roll your own particular auth
system, which can easily plug into the various hooks in Forms and Reports (e.g. field formatters, read-only checks, etc).
If necessary you can simply make new wrapper macros around these if/when boilerplate becomes an issue. After all, forms
and reports are just very thin macros around Fulcro's defsc
that pre-fill component options for you.
We hope the community will provide plugins for this, but generalized Auth is simply beyond the scope of RAD at this time due
to time/resource constraints. Community members are highly encouraged to write their own auth plugin libraries for
RAD, and we'll be glad to link to them on the main project pages.
The implementation in this namespace is only partially written, and can satisfy some simple needs. The original idea was that each attribute would be under some authority (the owner of that data). These would be identified by user-generated keyword names.
The state machine in this namespace was then meant to be used as a way to check which authorities had been authenticated against, so that incremental data access could be obtained over time as the user moved among features in the application. Each authority requires that the developer provide a component that can be used as the source of the mutation names and (optionally) UI for obtaining data from the user like passwords.
This at least gives you the ability to control if the current user is at least known to the authority in question, but even this requires some integration with the network remotes of your application (are you using cookies? JWT? etc.).
Also: Real Data access has to be ultimately controlled by the data owner. Therefore much of the real work needs to be done work at the network/database layer.
Securing a real application needs the following (most of which RAD does NOT provide a default implementation for):
Some ideas around possible implementations can be found in this package's source directory as auth.adoc.
Authentication and Authorization Support. WARNING: This part of RAD will not be standardized for some time. You will need to roll your own particular auth system, which can easily plug into the various hooks in Forms and Reports (e.g. field formatters, read-only checks, etc). If necessary you can simply make new wrapper macros around these if/when boilerplate becomes an issue. After all, forms and reports are just very thin macros around Fulcro's `defsc` that pre-fill component options for you. We hope the community will provide plugins for this, but generalized Auth is simply beyond the scope of RAD at this time due to time/resource constraints. Community members are highly encouraged to write their own auth plugin libraries for RAD, and we'll be glad to link to them on the main project pages. The implementation in this namespace is only partially written, and can satisfy some simple needs. The original idea was that each attribute would be under some authority (the owner of that data). These would be identified by user-generated keyword names. The state machine in this namespace was then meant to be used as a way to check which authorities had been authenticated against, so that incremental data access could be obtained over time as the user moved among features in the application. Each authority requires that the developer provide a component that can be used as the source of the mutation names and (optionally) UI for obtaining data from the user like passwords. This at least gives you the ability to control if the current user is at least *known* to the authority in question, but even this requires some integration with the network remotes of your application (are you using cookies? JWT? etc.). Also: *Real* Data access has to be ultimately controlled by the data owner. Therefore much of the real work needs to be done work at the network/database layer. Securing a real application needs the following (most of which RAD does NOT provide a default implementation for): * A way to auth against a server to establish a session. * A Pathom parser plugin that can check the query/mutation to see if it should be allowed. ** Optionally: granular query security, where individual attributes can be redacted. This would allow the same UI to be shown for users in different roles, and simple elision at the server can then easily be used to affect field/column visibility in the client. Some ideas around possible implementations can be found in this package's source directory as auth.adoc.
An implementation of an authorization system for applications that provides very simple logic:
determine
will only do routing async. All other requests immediately go through can?
.determine
for routing looks on the route target to see if an authority is required. If not, it simply answers
cached-true
immediately. If an authority is required but not present it will start an auth sequence with a request to
signal when that is complete.can?
looks for narrowed props for Read and Write permissions in the context
. If these are nil, then
it returns uncached-true
. E.g. :invoice/date
will look for :invoice.date/permissions
. Forms and
reports must be configured to ask for these additional properties, and resolvers must be configured to
provide them.An implementation of an authorization system for applications that provides very simple logic: * The `determine` will only do routing async. All other requests immediately go through `can?`. * `determine` for routing looks on the route target to see if an authority is required. If not, it simply answers `cached-true` immediately. If an authority is required but not present it will start an auth sequence with a request to signal when that is complete. * `can?` looks for narrowed props for Read and Write permissions in the `context`. If these are nil, then it returns `uncached-true`. E.g. `:invoice/date` will look for `:invoice.date/permissions`. Forms and reports must be configured to ask for these additional properties, and resolvers must be configured to provide them.
No vars found in this namespace.
Support for dealing with binary large objects (e.g. file upload, storage, and retrieval of images, documents, etc.)
To use this support you must:
file-upload/wrap-mutation-file-uploads
.file-upload/wrap-file-upload
HTTP remote request middleware.upload-file
mutation from this ns into your pathom resolver.::blob/temporary-store
to your Pathom env.::blob/stores
map to associate store names to Storage components to your Pathom env.Support for dealing with binary large objects (e.g. file upload, storage, and retrieval of images, documents, etc.) To use this support you must: - Add wrap-persist-images from this ns to your form save middleware - Install the Fulcro Ring middleware `file-upload/wrap-mutation-file-uploads`. - Configure an HTTP remote on the client with `file-upload/wrap-file-upload` HTTP remote request middleware. - Add the and install the `upload-file` mutation from this ns into your pathom resolver. - Add `::blob/temporary-store` to your Pathom env. - Add a `::blob/stores` map to associate store names to Storage components to your Pathom env. - Configure attributes that will handle files. This support assumes some storage adapter will store the URL of the file uploaded, and the file data will go in some other store (e.g. S3, disk, etc.). So, you configure a to-one string attribute with: ** The form field style to use a renderer that supports file uploads. ** ::blob/store to indicate the identifer of an implementation of blob-storage/Storage.
The protocol and a sample implementation of binary large object storage. Blob storage is used by the file upload support to first place files in a temporary holding area, and then support moving them to a more permanent store if/when the form that refers to the file is saved. Of course, storage can be persistent and just skip the transient bits if you don't need to track the files in some other kind of database.
The protocol and a sample implementation of binary large object storage. Blob storage is used by the file upload support to first place files in a temporary holding area, and then support moving them to a more permanent store if/when the form that refers to the file is saved. Of course, storage can be persistent and just skip the transient bits if you don't need to track the files in some other kind of database.
A RAD container is a component for grouping together reports. They allow you pull up controls to the container level to coordinate reports so that one set of controls is shared among them.
Reports may keep controls local to themselves by adding :local?
to a control; otherwise, all of the controls
from all nested reports will be pulled up to the container level and will be unified when their names match. The
container itself will then be responsible for asking the children to refresh (though technically you can add a local
control to any child to make such a control available for a particular child).
A RAD container is a component for grouping together reports. They allow you pull up controls to the container level to coordinate reports so that one set of controls is shared among them. Reports may keep controls local to themselves by adding `:local?` to a control; otherwise, all of the controls from all nested reports will be pulled up to the container level and will be unified when their names match. The container itself will then be responsible for asking the children to refresh (though technically you can add a local control to any child to make such a control available for a particular child).
Options specific to RAD containers.
Options specific to RAD containers.
Controls are buttons and inputs in the UI that are not backed by model data, but instead control things like report parameters or provide action buttons. This namespace provides functions to help with UI plugin development, and other functions that reduce the amount of boilerplate data when declaring controls.
A typical control is added to a component by adding a ::control/controls key, which is a map from made-up control key to a control definition map.
(defsc-form Form [this props]
{::control/controls {::new {:type :button
:label "Go"
:action (fn [this] ...)}}})
Render plugins can then expose layout keys that allow you to place the controls. For example as action buttons. See ::form/action-buttons.
Controls are buttons and inputs in the UI that are not backed by model data, but instead control things like report parameters or provide action buttons. This namespace provides functions to help with UI plugin development, and other functions that reduce the amount of boilerplate data when declaring controls. A typical control is added to a component by adding a ::control/controls key, which is a map from made-up control key to a control definition map. ``` (defsc-form Form [this props] {::control/controls {::new {:type :button :label "Go" :action (fn [this] ...)}}}) ``` Render plugins can then expose layout keys that allow you to place the controls. For example as action buttons. See ::form/action-buttons.
Options definitions and documentation for control options. Used by reports and containers.
Options definitions and documentation for control options. Used by reports and containers.
Support for consistent error reporting across all RAD projects/plugins. These errors report during development, but become no-ops in release builds that have zero overhead.
Support for consistent error reporting across all RAD projects/plugins. These errors report during development, but become no-ops in release builds that have zero overhead.
Helper functions when writing custom form state machines.
Helper functions when writing custom form state machines.
No vars found in this namespace.
Documented definitions of the standard form options. These provide easy access to documentation for the options, along with preventing spelling errors when using the keys in definitions. Plugin authors are encouraged to write their own options files to get the same benefits.
Forms currently require a minimum of two options:
id
attributes
NOTE to maintainers and Plugin authors: These files must be CLJC to make sure the symbols are resolvable at compile time. No dynamic tricks please. The form and report macros must be able to resolve the option symbols during evaluation.
Documented definitions of the standard form options. These provide easy access to documentation for the options, along with preventing spelling errors when using the keys in definitions. Plugin authors are encouraged to write their own options files to get the same benefits. Forms currently require a minimum of two options: * `id` * `attributes` NOTE to maintainers and Plugin authors: These files must be CLJC to make sure the symbols are resolvable at *compile* time. No dynamic tricks please. The form and report macros must be able to resolve the option symbols during evaluation.
Functions supporting various ID concerns.
Functions supporting various ID concerns.
ALPHA. Will almost certainly change.
ALPHA. Will almost certainly change.
Utilities for interpreting and coping with form/report options.
Utilities for interpreting and coping with form/report options.
Plugins and a default generated parser for working with RAD applications. You may use the source of this namespace
as reference for making your own custom parser, or simply start with the new-parser
function.
Plugins and a default generated parser for working with RAD applications. You may use the source of this namespace as reference for making your own custom parser, or simply start with the `new-parser` function.
Utilities to help support entity/enumeration pickers in the UI, along with loading/normalizing/caching the options.
Pickers are commonly used for things like autocomplete fields and (cascading) dropdowns where the list of options must be loaded dynamically due to some event in the UI.
Utilities to help support entity/enumeration pickers in the UI, along with loading/normalizing/caching the options. Pickers are commonly used for things like autocomplete fields and (cascading) dropdowns where the list of options must be loaded dynamically due to some event in the UI.
Support for generated reports. Report rendering is pluggable, so reports can be quite varied. The general definition of a report is a component that loads data and displays it, possibly paginates, sorts and filters it, but for which interactions are done via custom mutations (disable, delete, sort) or reloads.
Reports can customize their layout via plugins, and the layout can then allow futher nested customization of element render. For example, it is trivial to create a layout renderer that is some kind of graph, and then use loaded data as the input for that display.
Customizing the report's state machine and possibly wrapping it with more complex layout controls makes it possible to create UI dashboards and much more complex application features.
Support for generated reports. Report rendering is pluggable, so reports can be quite varied. The general definition of a report is a component that loads data and displays it, possibly paginates, sorts and filters it, but for which interactions are done via custom mutations (disable, delete, sort) or reloads. Reports can customize their layout via plugins, and the layout can then allow futher nested customization of element render. For example, it is trivial to create a layout renderer that is some kind of graph, and then use loaded data as the input for that display. Customizing the report's state machine and possibly wrapping it with more complex layout controls makes it possible to create UI dashboards and much more complex application features.
Documented definitions of the standard report options. These provide easy access to documentation for the options, along with preventing spelling errors when using the keys in definitions. Plugin authors are encouraged to write their own options files to get the same benefits.
Reports currently require a minimum of two options:
row-pk
columns
source-attribute
NOTE to maintainers and Plugin authors: These files must be CLJC to make sure the symbols are resolvable at compile time. No dynamic tricks please. The form and report macros must be able to resolve the option symbols during evaluation.
Documented definitions of the standard report options. These provide easy access to documentation for the options, along with preventing spelling errors when using the keys in definitions. Plugin authors are encouraged to write their own options files to get the same benefits. Reports currently require a minimum of two options: * `row-pk` * `columns` * `source-attribute` NOTE to maintainers and Plugin authors: These files must be CLJC to make sure the symbols are resolvable at *compile* time. No dynamic tricks please. The form and report macros must be able to resolve the option symbols during evaluation.
Support for allowing resolvers to be declared on attributes via ::pc/input ::pc/output and ::pc/resolve. This is useful because it allows custom resolution of an attribute that then has all of the RAD abilities attributes have.
(defattr server-time :server/time :inst
{::pc/output [:server/time]
::pc/resolver (fn [_ _] (java.util.Date.))
::form/label "Current Server Time"
::form/field-style :some-custom-style
...})
Then install them in your parser as a list of resolvers you can obtain from (resolvers/generate-resolvers all-attributes)
.
You may also, of course, define resolvers using defresolver
and other pathom functions, but you must install those
separately.
Support for allowing resolvers to be declared on attributes via ::pc/input ::pc/output and ::pc/resolve. This is useful because it allows custom resolution of an attribute that then has all of the RAD abilities attributes have. ``` (defattr server-time :server/time :inst {::pc/output [:server/time] ::pc/resolver (fn [_ _] (java.util.Date.)) ::form/label "Current Server Time" ::form/field-style :some-custom-style ...}) ``` Then install them in your parser as a list of resolvers you can obtain from `(resolvers/generate-resolvers all-attributes)`. You may also, of course, define resolvers using `defresolver` and other pathom functions, but you must install those separately.
A support layer for application-level routing. RAD supports the idea of an application-level history. This allows it to abstract over the concepts of relative navigation since it can be used on many platforms (like React Native or Electron) where no natural browser history API exists.
History support in RAD requires that you install an implementation of RouteHistory at application start time. See
com.fulcrologic.rad.routing.history
and associated namespaces.
Functions in this namespace that do relative routing will silently fail if no such history support is installed.
A support layer for application-level routing. RAD supports the idea of an *application-level* history. This allows it to abstract over the concepts of relative navigation since it can be used on many platforms (like React Native or Electron) where no natural browser history API exists. History support in RAD requires that you install an implementation of RouteHistory at application start time. See `com.fulcrologic.rad.routing.history` and associated namespaces. Functions in this namespace that do relative routing will silently fail if no such history support is installed.
Generic history protocol and support.
In order to use history, you must install an implementation on your Fulcro app at application start-time that
is compatible with your runtime environment (browser, native mobile, etc.) via install-route-history!
. Once
you've done that, then the non-protocol methods in this namespace can be used against the app to update the history,
but they will not affect the actual application route. Actual routing should always be done via the
com.fulcrologic.rad.routing
namespace functions, which will keep track of history if it is installed.
Generic history protocol and support. In order to use history, you must install an implementation on your Fulcro app at application start-time that is compatible with your runtime environment (browser, native mobile, etc.) via `install-route-history!`. Once you've done that, then the non-protocol methods in this namespace can be used against the app to update the *history*, but they will *not* affect the actual *application route*. Actual routing should always be done via the `com.fulcrologic.rad.routing` namespace functions, which will keep track of history if it is installed.
An implementation of RAD's RouteHistory protocol, wrapping a browser's location and History API. This implementation will put an string-valued route parameters onto the query parameter section of the URI when a route is pushed or replaced, and will merge the current URL's query parameters with returned route params.
An implementation of RAD's RouteHistory protocol, wrapping a browser's location and History API. This implementation will put an string-valued route parameters onto the query parameter section of the URI when a route is pushed or replaced, and will merge the current URL's query parameters with returned route params.
A Report state machine that is tuned to work with large data sets on the server, where a small subset of the data is loaded at any given time, and the server is responsible for sorting and filtering. Requires that the data's resolver supports parameters that indicate the current sort key, sort direction, and filter(s).
A Report state machine that is tuned to work with large data sets on the server, where a small subset of the data is loaded at any given time, and the server is responsible for sorting and filtering. Requires that the data's resolver supports parameters that indicate the current sort key, sort direction, and filter(s).
No vars found in this namespace.
A common set of date/time functions for CLJC. Libraries like tick
are promising, and CLJC time is useful
(and used by this ns), but cljc-time does not have an interface that is the same between the two languages,
and tick is alpha (and often annoying).
A common set of date/time functions for CLJC. Libraries like `tick` are promising, and CLJC time is useful (and used by this ns), but cljc-time does not have an interface that is the same between the two languages, and tick is alpha (and often annoying).
Support for CLJC arbitrary precision decimal numerics. CLJ support for BigDecimal works well, but it is not directly supported in CLJS. Use the support in this ns when you need to write CLJC code that works the same in both.
You MUST include big.js as a js dependency for this to compile in CLJS.
Support for CLJC arbitrary precision decimal numerics. CLJ support for BigDecimal works well, but it is not directly supported in CLJS. Use the support in this ns when you need to write CLJC code that works the same in both. You MUST include big.js as a js dependency for this to compile in CLJS.
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close