Outerfaces.Odd.RouteManifest (Outerfaces Dependency Distribution (ODD) v0.2.7)
View SourceA project's client routes, kept on the server and handed to each visitor filtered by what they may reach, with the same rules deciding which of the project's files they may fetch.
The manifest is a JSON file in the project (routes.manifest.json by
convention), read by the server and never served:
{
"default_access": "signed_in",
"title_suffix": " | Example",
"sign_in": {"grant": "signed_in", "path": "/sign-in", "return_param": "next"},
"public_files": ["index.js", "styles/", "pages/sign-in-page.js"],
"files_access": "signed_in",
"entries": {"signed_in": ["/elements/index.js"]},
"routes": [
{"app_path": "/", "page_path": "/pages/home-page.js", "slug": "home", "title": "Home"},
{"app_path": "/sign-in", "page_path": "/pages/sign-in-page.js", "slug": "sign_in",
"title": "Sign in", "access": "public"}
]
}Grants are strings a request holds, decided by the host application
("signed_in", a permission name, a plan): "public" is always held. A
route is visible when its access (else default_access, else "public")
is a held grant.
sign_in: a visitor without itsgrantwho asks for any path outside their routes is sent to itspath, with where they were going inreturn_param. Missing and hidden routes answer alike, so a signed-out visitor learns nothing about routes they can't see.public_files: the files anyone may fetch (a name, or a folder ending in/), and with them every module they and the public routes' pages import (public_closure/2), read from the files as served, so a build that bundles or renames modules stays covered. Every other file needsfiles_access(defaultdefault_access). Withoutpublic_files, every file is public.entries: per grant, modules the shell imports at start when the visitor holds it (code only a signed-in shell needs).
Summary
Types
What a request holds; "public" is always among them.
What a path is to a visitor: one of their routes, a path for which they must sign in first, a route they can't reach, or nothing.
A decoded manifest, string keys as in the file.
Functions
What the shell is given: the visitor's routes (titles with the suffix), the
entries their grants open, and sign_in while they lack its grant.
Whether a visitor holding grants may fetch the project file at
relative_path ("pages/home-page.js", no leading slash). public is the
project's public_closure/2.
grants with "public", each once.
html with payload as <script type="application/json" id="outerfaces-routes">, just before </head>. The JSON is escaped so
nothing in it can close the script element.
Reads and decodes the manifest at path, cached until the file changes.
As load/1, raising when the manifest can't be read.
The modules a signed-out shell may load beyond those listed: the import
closure of the listed public_files modules and of the pages of the routes
anyone may reach, as relative paths under root (the served project).
Relative (./, ../) and root (/elements/...) specifiers are followed,
through static imports, re-exports and literal dynamic imports; bare
specifiers (shared libraries) are not. Cached, and worked out again when
the manifest or any module in the closure changes.
Whether anyone may fetch the file at relative_path: it is listed in
public_files, or in public (the project's public_closure/2).
Whether request_path is the route app_path: a :name segment matches
any one non-empty segment, and a trailing slash is ignored.
What request_path is to a visitor holding grants (see status/0).
The routes a visitor holding grants may reach, in manifest order.
Types
Functions
What the shell is given: the visitor's routes (titles with the suffix), the
entries their grants open, and sign_in while they lack its grant.
Whether a visitor holding grants may fetch the project file at
relative_path ("pages/home-page.js", no leading slash). public is the
project's public_closure/2.
grants with "public", each once.
html with payload as <script type="application/json" id="outerfaces-routes">, just before </head>. The JSON is escaped so
nothing in it can close the script element.
Reads and decodes the manifest at path, cached until the file changes.
As load/1, raising when the manifest can't be read.
The modules a signed-out shell may load beyond those listed: the import
closure of the listed public_files modules and of the pages of the routes
anyone may reach, as relative paths under root (the served project).
Relative (./, ../) and root (/elements/...) specifiers are followed,
through static imports, re-exports and literal dynamic imports; bare
specifiers (shared libraries) are not. Cached, and worked out again when
the manifest or any module in the closure changes.
Whether anyone may fetch the file at relative_path: it is listed in
public_files, or in public (the project's public_closure/2).
Whether request_path is the route app_path: a :name segment matches
any one non-empty segment, and a trailing slash is ignored.
What request_path is to a visitor holding grants (see status/0).
The routes a visitor holding grants may reach, in manifest order.