@zerotal/flow 1.7.3 → 1.7.4
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 +25 -16
- package/api-surface.md +2 -2
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,26 @@ change.
|
|
|
11
11
|
|
|
12
12
|
## [Unreleased]
|
|
13
13
|
|
|
14
|
+
## [1.7.3] — 2026-08-20
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **A bound password field silently discarded every keystroke.** The client-writable set was
|
|
19
|
+
`fillable` minus `hidden`, which conflates two allow-lists that answer different questions:
|
|
20
|
+
`fillable`/`guarded` govern what may be _written_, `visible`/`hidden` govern what may be
|
|
21
|
+
_shown_. A password is in both — fillable because a user sets it, hidden because the stored
|
|
22
|
+
hash must never reach a page — so subtracting made it unwritable, and
|
|
23
|
+
`<input type="password" value={this.user.password} blur />` accepted typing and dropped it
|
|
24
|
+
on arrival. `hidden` is no longer subtracted. It is still never _sent_: the hash does not
|
|
25
|
+
leave the server, and the field arrives empty as it should. A hidden value the client
|
|
26
|
+
supplied now survives until save, and one the _server_ produced is never echoed back.
|
|
27
|
+
|
|
28
|
+
A half-typed secret is also stripped from the [durable snapshot](/docs/flow/lifecycle)
|
|
29
|
+
before it is persisted — that store is written server-side after every request and may be
|
|
30
|
+
backed by Redis, which is no place for a password in progress.
|
|
31
|
+
|
|
32
|
+
## [1.7.2] — 2026-08-18
|
|
33
|
+
|
|
14
34
|
### Added
|
|
15
35
|
|
|
16
36
|
- **`@on` can name a channel per instance.** A listener's channel is read off the _class_, so
|
|
@@ -52,20 +72,6 @@ change.
|
|
|
52
72
|
|
|
53
73
|
### Fixed
|
|
54
74
|
|
|
55
|
-
- **A bound password field silently discarded every keystroke.** The client-writable set was
|
|
56
|
-
`fillable` minus `hidden`, which conflates two allow-lists that answer different questions:
|
|
57
|
-
`fillable`/`guarded` govern what may be _written_, `visible`/`hidden` govern what may be
|
|
58
|
-
_shown_. A password is in both — fillable because a user sets it, hidden because the stored
|
|
59
|
-
hash must never reach a page — so subtracting made it unwritable, and
|
|
60
|
-
`<input type="password" value={this.user.password} blur />` accepted typing and dropped it
|
|
61
|
-
on arrival. `hidden` is no longer subtracted. It is still never _sent_: the hash does not
|
|
62
|
-
leave the server, and the field arrives empty as it should. A hidden value the client
|
|
63
|
-
supplied now survives until save, and one the _server_ produced is never echoed back.
|
|
64
|
-
|
|
65
|
-
A half-typed secret is also stripped from the [durable snapshot](/docs/flow/lifecycle)
|
|
66
|
-
before it is persisted — that store is written server-side after every request and may be
|
|
67
|
-
backed by Redis, which is no place for a password in progress.
|
|
68
|
-
|
|
69
75
|
- **`<FileUpload>` never stopped saying "Uploading… 100%".** A successful upload left the
|
|
70
76
|
dropzone reporting progress forever. The bytes had gone up, the signed reference had come
|
|
71
77
|
back, and the bound property had been set — the only thing that failed was the component
|
|
@@ -115,20 +121,23 @@ change.
|
|
|
115
121
|
|
|
116
122
|
### Documented
|
|
117
123
|
|
|
118
|
-
Four behaviours that were true but written down nowhere, each found by hitting it:
|
|
119
|
-
|
|
120
124
|
- **AOT compilation and `__()` are mutually exclusive** — a function call in a text child forces
|
|
121
125
|
the runtime fallback, so a translated app compiles no pages at all. Normally that is a speed
|
|
122
126
|
cost; under `cspSafe`, where every page must compile, it is a build failure. `performance.md`
|
|
123
127
|
now lists what blocks compilation and what to do about it.
|
|
128
|
+
|
|
124
129
|
- **`FlowTest` opens no request scope**, so `Auth.user()` and `Auth.attempt()` throw and no
|
|
125
130
|
action behind a sign-in can be driven without wrapping it. `testing.md` carries the wrapper.
|
|
131
|
+
|
|
126
132
|
- **A layout cannot set the document's `lang`** — Flow emits `<html lang="en">` and offers no
|
|
127
133
|
hook, so a localised app marks up its wrapper instead and the root element stays wrong.
|
|
134
|
+
|
|
128
135
|
- **`<Tabs>` selection is client-only and its strip is not themeable** — no bindable prop, so no
|
|
129
136
|
`?tab=`, no back button, and hardcoded gray/indigo that is invisible on a light surface.
|
|
137
|
+
|
|
130
138
|
- **Flow and `zerotal/view` components do not interoperate** — the two JSX runtimes produce
|
|
131
139
|
different element types (`HtmlNode` vs `SafeHtml`), so a view `FC` in a Flow page is `TS2786`.
|
|
140
|
+
|
|
132
141
|
- **`onSort` does not say which container took the drop** — the destination is encoded in which
|
|
133
142
|
method runs, so dragging between containers needs one action per container.
|
|
134
143
|
|
package/api-surface.md
CHANGED
|
@@ -1026,7 +1026,7 @@ interface VirtualizeProps = {
|
|
|
1026
1026
|
|
|
1027
1027
|
type Constructor = abstract new (...args: any[]) => T
|
|
1028
1028
|
|
|
1029
|
-
type DurableOption = boolean | {
|
|
1029
|
+
type DurableOption = boolean | { ttl?: string; scope?: 'user' | 'session' }
|
|
1030
1030
|
|
|
1031
1031
|
type EventName = never
|
|
1032
1032
|
|
|
@@ -1040,7 +1040,7 @@ type FlashPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' |
|
|
|
1040
1040
|
|
|
1041
1041
|
type HtmlNode = { html: string;}
|
|
1042
1042
|
|
|
1043
|
-
type ListenerName =
|
|
1043
|
+
type ListenerName = LooseEventName | ((self: Record<string, any>) => string)
|
|
1044
1044
|
|
|
1045
1045
|
type Mixin = (Base: TIn) => TOut
|
|
1046
1046
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zerotal/flow",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"maturity": "stable",
|
|
6
6
|
"private": false,
|
|
@@ -47,15 +47,15 @@
|
|
|
47
47
|
"@alpinejs/morph": "^3.14.9",
|
|
48
48
|
"@alpinejs/persist": "^3.14.9",
|
|
49
49
|
"@alpinejs/resize": "^3.14.9",
|
|
50
|
-
"@zerotal/client": "1.7.
|
|
51
|
-
"@zerotal/core": "1.7.
|
|
52
|
-
"@zerotal/orm": "1.7.
|
|
53
|
-
"@zerotal/validator": "1.7.
|
|
50
|
+
"@zerotal/client": "1.7.4",
|
|
51
|
+
"@zerotal/core": "1.7.4",
|
|
52
|
+
"@zerotal/orm": "1.7.4",
|
|
53
|
+
"@zerotal/validator": "1.7.4",
|
|
54
54
|
"alpinejs": "^3.14.9",
|
|
55
55
|
"typescript": "^5.8.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@zerotal/broadcasting": "1.7.
|
|
58
|
+
"@zerotal/broadcasting": "1.7.4",
|
|
59
59
|
"@types/alpinejs": "^3.13.10",
|
|
60
60
|
"@types/alpinejs__anchor": "^3.13.1",
|
|
61
61
|
"@types/alpinejs__collapse": "^3.13.4",
|