@plitzi/sdk-server 0.38.7 → 0.38.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +73 -0
- package/README.md +10 -5
- package/dist/core/createServer.notFound.test.d.ts +1 -0
- package/dist/core/oauth/consentPage.js +1 -9
- package/dist/core/unusedPort.d.ts +6 -0
- package/dist/core/unusedPort.js +20 -0
- package/dist/helpers/compress.js +1 -1
- package/dist/helpers/escapeHtml.d.ts +2 -0
- package/dist/helpers/escapeHtml.js +13 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -1
- package/dist/modules/actions/runtime/errors.d.ts +6 -0
- package/dist/modules/actions/runtime/errors.js +7 -1
- package/dist/modules/actions/runtime/projectData.js +1 -1
- package/dist/modules/actions/runtime/runAction.js +2 -2
- package/dist/modules/functions/routes.js +2 -2
- package/dist/modules/project/plugins.d.ts +1 -1
- package/dist/modules/project/plugins.js +2 -2
- package/dist/modules/project/serveProject.js +40 -12
- package/dist/modules/project/spaceFailure.d.ts +8 -0
- package/dist/modules/project/spaceFailure.js +76 -0
- package/dist/modules/runtime/bundle.d.ts +1 -1
- package/dist/modules/runtime/bundle.js +1 -1
- package/dist/modules/runtime/runner.d.ts +1 -0
- package/dist/modules/runtime/runner.js +2 -3
- package/dist/modules/ssr/applySSRResult.d.ts +11 -0
- package/dist/modules/ssr/applySSRResult.js +14 -1
- package/dist/modules/ssr/buildBody.js +2 -0
- package/dist/modules/ssr/handler.js +2 -2
- package/dist/modules/ssr/prepareRender.d.ts +2 -0
- package/dist/modules/ssr/prepareRender.js +9 -3
- package/dist/modules/ssr/streamBody.js +3 -2
- package/package.json +3 -3
- package/skills/plitzi-authoring/SKILL.md +34 -149
- package/skills/plitzi-authoring/recipes/detail-page.ts +4 -2
- package/skills/plitzi-authoring/recipes/plugin.ts +1 -1
- package/skills/plitzi-authoring/reference/accessibility.md +3 -2
- package/skills/plitzi-authoring/reference/authoring-errors.md +4 -0
- package/skills/plitzi-authoring/reference/drawing.md +1 -1
- package/skills/plitzi-authoring/reference/flows.md +6 -4
- package/skills/plitzi-authoring/reference/index.md +33 -0
- package/skills/plitzi-authoring/reference/layouts.md +18 -0
- package/skills/plitzi-authoring/reference/plugins.md +2 -2
- package/skills/plitzi-authoring/reference/recipes.md +25 -0
- package/skills/plitzi-authoring/reference/rules.md +61 -0
- package/skills/plitzi-authoring/reference/snippets-and-export.md +2 -2
- package/skills/plitzi-authoring/reference/structure.md +1 -1
- package/skills/plitzi-authoring/reference/testing.md +1 -1
- package/skills/plitzi-authoring/reference/validation.md +1 -1
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# The rules of writing a space
|
|
2
|
+
|
|
3
|
+
Every rule, with its why. The skill's core keeps the five that go wrong most in a line each; the rest authoring
|
|
4
|
+
refuses or warns of, with the fix.
|
|
5
|
+
|
|
6
|
+
1. **Name what is referred to.** Give an `id` to every element a binding, a flow or a test addresses. Ids are ONE
|
|
7
|
+
namespace for the whole space — layouts and every page share it — so a helper that runs more than once builds inside
|
|
8
|
+
`scope('promos', ref => …)`: every id in it is prefixed (`promos-panel`), and `ref('slides')` names one in full. An `id` is the element's name in the
|
|
9
|
+
space (`data-plitzi-el` in the page); the DOM id a URL's `#fragment` lands on is its `anchor`.
|
|
10
|
+
2. **Share with classes, layouts and components, never with copies.** A look used twice is a `styles()` class.
|
|
11
|
+
Chrome shown on several pages — a header, a sidebar, a footer — is a **layout** the pages name, written once. A block
|
|
12
|
+
placed many times with different content — a product card, a testimonial — is a **component** placed with
|
|
13
|
+
`component(id, { props })`. A menu, a card grid, a list of steps is DATA, never a block pasted per item: a short
|
|
14
|
+
menu mapped in code is fine; rows — cards, dishes, tiles — are one `list` (`items: [ … ]`) whose row is written
|
|
15
|
+
once. A link or a button says its words as
|
|
16
|
+
its own `content`, not through a `text` inside it. Pages of one shape are one `pageFamily` over data. See
|
|
17
|
+
[layouts](layouts.md), [components](components.md), [structure](structure.md) and
|
|
18
|
+
[efficiency](efficiency.md).
|
|
19
|
+
3. **One element, one base selector.** An element takes a shared `class` OR its own `css`, never both — authoring
|
|
20
|
+
refuses the pair. "This class plus one thing" is the class with rules on top, last in the list:
|
|
21
|
+
`class: [cover, { opacity: '0.25' }]` (needs the element's `id`; it becomes the class `<id>--own`). A look that
|
|
22
|
+
never changes is its own class.
|
|
23
|
+
4. **Visible by default; decide which way the logic flips.** An element is on screen unless something hides it. When
|
|
24
|
+
the logic REVEALS it (hidden → shown: an empty state, a "get started" card, an admin-only panel), it starts hidden —
|
|
25
|
+
`visible: 'source'`, or `visible: false` plus a binding for a computed condition — so it never flashes while data
|
|
26
|
+
loads (`condition-starts-visible` warns). When a flag HIDES it (shown → hidden: a sidebar label until the sidebar
|
|
27
|
+
is folded), it keeps the default and an absent flag must leave it shown. See
|
|
28
|
+
[data and visibility](data-and-visibility.md). What a PERSON switches on — a feature in beta, a rollout —
|
|
29
|
+
is a feature flag, not a visibility: gated off, it is not rendered at all. See [feature flags](feature-flags.md).
|
|
30
|
+
5. **Know where a template is evaluated.** A binding's template (`bindTemplate`) and a step's params evaluate full
|
|
31
|
+
Twig. An ATTRIBUTE resolves a name with filters (`{{ list_games.item.slug }}`, `{{ post.slug|url_encode }}`) against
|
|
32
|
+
the sources around the element; a condition there is used as written. Inside any template a source is spelled in
|
|
33
|
+
full — `apiContainer_stats`, `list_rows` — and a query param is `navigation.queryParams.x`. A template that feeds a
|
|
34
|
+
list its `items` hands over its value (`returns: 'value'`). `authorSpace` refuses a template it cannot read and a
|
|
35
|
+
name nothing answers to. See [templates](templates.md).
|
|
36
|
+
6. **Tokens, not colours.** Every colour is a variable of the space with a `light` and a `dark` value; both themes are
|
|
37
|
+
checked from the first commit.
|
|
38
|
+
7. **Times in UTC, and say so.** Format with an explicit zone (`|date('j M · H:i', 'UTC')`) and print "UTC" beside it:
|
|
39
|
+
a page rendered on a server and hydrated in a browser in another zone must agree on the hour.
|
|
40
|
+
8. **Breakpoints are ranges.** `tablet` (48–64rem) and `mobile` (up to 48rem) each inherit only from `desktop`; a rule
|
|
41
|
+
meant for both is written under `compact`.
|
|
42
|
+
9. **Never invent data.** Numbers, names and states on screen come from a source. A panel with nothing true to say is
|
|
43
|
+
an empty state, not a placeholder figure. With no backend, the data is JSON read by an `apiContainer`: a server
|
|
44
|
+
project's `src/data/*.json`, read on the server and never served; with no server, `public/data/*.json`, which is
|
|
45
|
+
public — see [data and visibility](data-and-visibility.md).
|
|
46
|
+
10. **Never hand-write** `flat`, derived ids, `styleSelectors`, `beforeNode`/`afterNode`/`flowId`, or a
|
|
47
|
+
`styleVariant` binding's key — use the factories, `variantFrom` and `activeOn`.
|
|
48
|
+
11. **A switch is named for how it leaves its default.** `toggleState` turns a key nobody has set yet ON, so a key
|
|
49
|
+
named for the default (`showPlates`, on by default) takes a first click to do nothing: name it `platesOff`, and read
|
|
50
|
+
every switch through `computed` (`plates: '{{ state.platesOff ? false : true }}'`) so its default shows before
|
|
51
|
+
anybody touches it.
|
|
52
|
+
12. **Hand plugins over as their declarations**: `authorSpace(space, { plugins: [declaration] })` holds a plugin —
|
|
53
|
+
its own type, or a `custom({ renderType })` host — to the events, actions and attributes it declares. See
|
|
54
|
+
[plugins](plugins.md).
|
|
55
|
+
13. **Usable without sight.** Screen readers and browser agents (Claude in Chrome) find a page's controls in its
|
|
56
|
+
accessibility tree: every button and link has words (an icon-only button a `title`), every field a `label`
|
|
57
|
+
(`hideLabel: true` hides it and keeps the name), every image an `alt` or `decorative: true`. Clicks go on a
|
|
58
|
+
`button` — it holds children, so a whole card can be one — or a `link`, never on a container. See
|
|
59
|
+
[accessibility](accessibility.md).
|
|
60
|
+
14. **Motion that stays smooth.** Animate `opacity` and `transform` only; no animated blur, shadow or size. See
|
|
61
|
+
[motion](colours-and-motion.md).
|
|
@@ -31,8 +31,8 @@ Never rewrite an exported space by hand. `specFromSpace({ schema, style })` read
|
|
|
31
31
|
A server action reads back the same way: `actionSpecFromEntry({ id, document })` gives the `defineAction` spec that writes
|
|
32
32
|
it — only when that spec writes the very same document, otherwise `reason` says why and it stays JSON — and
|
|
33
33
|
`actionToSource(spec)` writes the module. For the whole space as a project — pages, actions, functions, the source of
|
|
34
|
-
its plugins and runtime, its files — use `plitzi create --from <space>` (then `plitzi pull` to bring the space's changes in, and
|
|
35
|
-
`plitzi push` to put the project's back) rather than exporting the parts by hand.
|
|
34
|
+
its plugins and runtime, its files — use `plitzi create --from <space>` (then `plitzi space pull` to bring the space's changes in, and
|
|
35
|
+
`plitzi space push` to put the project's back) rather than exporting the parts by hand.
|
|
36
36
|
|
|
37
37
|
For a document you did not author — an export, a JSON edited by hand — run the gate before serving it:
|
|
38
38
|
`validateSpace({ schema, style })`.
|
|
@@ -117,7 +117,7 @@ the rest.
|
|
|
117
117
|
|
|
118
118
|
## Checked for you
|
|
119
119
|
|
|
120
|
-
`npm run lint:space` (`plitzi lint`) reads the source for what this page asks — a file past 400 lines, pages in one
|
|
120
|
+
`npm run lint:space` (`plitzi space lint`) reads the source for what this page asks — a file past 400 lines, pages in one
|
|
121
121
|
file, rows of data inline, a colour that is not a token, CSS copied three times, a row singled out by its id inside a
|
|
122
122
|
`map`, a minted id, a file nothing imports — at file:line, beside authoring's suggestions. Leave it clean; a departure
|
|
123
123
|
on purpose says why where it is: `// plitzi-lint-disable-next-line <code> -- why` for lint's own codes. A suggestion of
|
|
@@ -71,7 +71,7 @@ the space with it (the e2e harness: `renderSpace(page, space, { debugMode: true
|
|
|
71
71
|
|
|
72
72
|
## Asking the page what it holds
|
|
73
73
|
|
|
74
|
-
`plitzi check` lists every flow that failed while the page loaded; `--state` adds the state and every source by its
|
|
74
|
+
`plitzi page check` lists every flow that failed while the page loaded; `--state` adds the state and every source by its
|
|
75
75
|
full name, `--element <id>` one element — what it reads, its own state, whether it is on screen. They come from the
|
|
76
76
|
page's dev tools (debug mode, any development server). In a test, `readDevTools(page, { state: true })` from
|
|
77
77
|
`@plitzi/sdk-authoring` answers the same.
|
|
@@ -46,7 +46,7 @@ bar.
|
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
2. **Fix, re-run, until it prints zero warnings.** What has one fix (`author` says how many) is written for you: `npx
|
|
49
|
-
plitzi fix` shows it as a diff of your source, `--write` writes it and keeps it only if the space authors with each
|
|
49
|
+
plitzi space fix` shows it as a diff of your source, `--write` writes it and keeps it only if the space authors with each
|
|
50
50
|
fix gone and nothing new — a fix it cannot place, or that would add a problem, is said with the reason. A
|
|
51
51
|
suggestion with one reading is written the same way (`content-attribute`: words and an icon held as children become
|
|
52
52
|
the button's or link's own `content` and `icon`). Then typecheck the project.
|