An app built from what is granted
The screens a person resolves to, handed to a Nova shell. The shell is asked for one it was given and one it was not.
pnpm add @niscorp/charter @niscorp/nova @niscorp/prism @niscorp/strata zodThree screens, and a charter
Each screen is a Nova action: an id and a layout. Together they are everything the app ships.
The charter gives a member two of them.
import { resolvePrincipal } from '@niscorp/charter';
import { createComponentRegistry, createShell, type ActionDefinition } from '@niscorp/nova';
const shipped: Record<string, ActionDefinition> = {
programme: { id: 'programme', layout: { component: 'Text', children: 'This week' } },
seats: { id: 'seats', layout: { component: 'Text', children: 'Pick your seats' } },
takings: { id: 'takings', layout: { component: 'Text', children: 'Tonight: 4,180' } },
};
const charter = { member: ['programme', 'seats'], manager: ['*'] };Keep what is granted
The member’s roles are resolved over the ids that exist. The app for this person is the screens in that set, and only those.
const granted = resolvePrincipal(charter, Object.keys(shipped), ['member']);
const theirs = Object.fromEntries(Object.entries(shipped).filter(([id]) => granted.has(id)));Build their shell
A shell is made from the screens it is handed. This is what Moss does on the server for each person who signs in, and it is where the charter is enforced.
Nova itself has no charter. A shell made in a browser from everything the page ships holds everything. The enforcement is that the server never puts the other screens in.
const shell = createShell({ canvases: [{ id: 'main' }], registry: createComponentRegistry(), actions: theirs });Ask for two screens
A screen is opened by its id. The one the member was given opens. The other is not hidden or locked: the shell has never heard of it, and says so.
for (const id of ['seats', 'takings']) {
try {
shell.push('main', id);
console.log(id + ': opened');
} catch (error) {
console.log(id + ':', error instanceof Error ? error.message : error);
}
}Run it.
The screen that was granted opens, and the one that was not is unknown to the shell.
npx tsx app.mtsseats: opened takings: Unknown action: takings