studio-engine 0.67.2 → 0.68.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -0
- data/README.md +48 -0
- data/app/views/style/modals/_auth.html.erb +67 -44
- data/lib/studio/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cc639657a629af209c7afe28ae5114aff1d6121a0c6e5fc456c0d7fec51a40b3
|
|
4
|
+
data.tar.gz: 4875b0355b16ea935f873f4dca59d1657a2e8b7e2b7b7ae17f79df80ea194e48
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 867c4b70c5c76e7619c6b4ed1d087a79ccb1cd3c9d99770f109c4c039d56372ca7835a3281d00bcc1fc076cb1759c700156959db4f29010e4fa5239b3a344944
|
|
7
|
+
data.tar.gz: 31eec34f181c1caec640f1085d97b3437bd6e0416e90ff4f4d23af29039b88406093ed42adbd11c973ef4a7687eeea76e208f5b57df88d25e66f37a937933bae
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,34 @@ The format is [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). This pro
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- **The auth modal's Solana button moved to solana-studio, behind a CREDENTIAL
|
|
10
|
+
SLOT.** `style/modals/_auth` no longer draws the button; it renders whatever
|
|
11
|
+
resolves at `solana_studio/auth/wallet_credential` and nothing when that path
|
|
12
|
+
is empty, so bundling the gem IS the registration and a web2 app carries no
|
|
13
|
+
wallet markup at all. This completes the two-template split begun in 0.67.0,
|
|
14
|
+
which moved the four web3 MODALS to the gem and left the sign-in button as the
|
|
15
|
+
last web3 markup in the base engine. The gem half has shipped since
|
|
16
|
+
solana-studio **0.5.2** — until now this engine referenced that partial
|
|
17
|
+
nowhere, so the gem shipped a button no host rendered.
|
|
18
|
+
**Supersedes the stranded PR #245**, whose consumer lane was red only because
|
|
19
|
+
it opened before solana-studio 0.5.2 published.
|
|
20
|
+
|
|
21
|
+
**What did NOT change, deliberately:** `_methodDefaults.wallet` is still
|
|
22
|
+
`Studio.auth_method?(:wallet) && Studio.feature?(:web3)`. The Ruby gate
|
|
23
|
+
answers "is it implemented" (is the picker registered, does the credential
|
|
24
|
+
partial resolve) and gates the RENDER; Alpine's `methodOn('wallet')` still
|
|
25
|
+
answers "should it show" and gates VISIBILITY, which keeps the style guide's
|
|
26
|
+
method toggles working. Folding policy into the Ruby gate would delete the
|
|
27
|
+
button from the DOM on a web3-off app that bundles the gem, and the "or"
|
|
28
|
+
divider — which reads `methodOn('wallet')` too — would then float above a
|
|
29
|
+
button that is not there.
|
|
30
|
+
|
|
31
|
+
Hosts need no change: the engine's auth modal is a style-guide specimen
|
|
32
|
+
reached through `/admin/style`, and an app that bundles solana-studio 0.5.2 or
|
|
33
|
+
later sees the same button in the same place.
|
|
34
|
+
|
|
7
35
|
### Fixed
|
|
8
36
|
|
|
9
37
|
- **Knowledge layer hardening** — the five findings from the 0.67.0 reviews:
|
data/README.md
CHANGED
|
@@ -257,6 +257,54 @@ What the engine **keeps** is the SESSION half of Solana sign-in:
|
|
|
257
257
|
`Studio.wallet_sign_in_statement` — the single source for the signed statement,
|
|
258
258
|
which the gem's deep link reads so the two cannot drift.
|
|
259
259
|
|
|
260
|
+
#### The auth modal's credential slot
|
|
261
|
+
|
|
262
|
+
The **sign-in modal itself stays here** and is never forked: every app in the
|
|
263
|
+
ecosystem signs people in, and most of them are web2. What varies is *which
|
|
264
|
+
credentials it offers*. Google and magic-link are implemented by this engine and
|
|
265
|
+
render directly. The wallet button is implemented by the web3 layer, so it is
|
|
266
|
+
**contributed** — `style/modals/_auth` looks for a partial at one fixed path and
|
|
267
|
+
renders whatever it finds:
|
|
268
|
+
|
|
269
|
+
solana_studio/auth/_wallet_credential (shipped by the solana-studio gem)
|
|
270
|
+
|
|
271
|
+
Bundling the gem **is** the registration. There is no registry call and no
|
|
272
|
+
config flag; an app without that layer renders nothing there, so a web2 app
|
|
273
|
+
carries no wallet markup at all rather than markup hidden behind a flag. This is
|
|
274
|
+
the same optional-partial convention as `modals/_host_extras` above, and it uses
|
|
275
|
+
the same three-term `lookup_context.exists?`.
|
|
276
|
+
|
|
277
|
+
Copying the auth modal into the gem was rejected deliberately: it would fork a
|
|
278
|
+
surface both apps sign in through, and the two copies would drift — which is how
|
|
279
|
+
the wallet picker reached three copies before it was promoted.
|
|
280
|
+
|
|
281
|
+
**Two layers answer two different questions, and they are not merged:**
|
|
282
|
+
|
|
283
|
+
| Question | Answered by | Where it is decided |
|
|
284
|
+
|---|---|---|
|
|
285
|
+
| Is it **implemented**? | the picker is registered, **and** the credential partial resolves | Ruby, in `style/modals/_auth` — gates the render |
|
|
286
|
+
| Should it **show**? | `methodOn('wallet')`, falling back to `Studio.auth_method?(:wallet) && Studio.feature?(:web3)` | Alpine, inside the contributed partial — gates visibility |
|
|
287
|
+
|
|
288
|
+
Both terms of the Ruby gate are load-bearing, and they fail differently. Without
|
|
289
|
+
the **registration** term a layer that ships the credential but not the picker
|
|
290
|
+
draws a button that opens an empty panel — not hypothetical, solana-studio 0.5.2
|
|
291
|
+
shipped exactly that pair. Without the **existence** term an app whose picker
|
|
292
|
+
resolves but whose credential does not raises `Missing partial` in front of
|
|
293
|
+
someone signing in, instead of quietly rendering no button.
|
|
294
|
+
|
|
295
|
+
Policy stays **out** of the Ruby gate on purpose. Folding
|
|
296
|
+
`auth_method?(:wallet)` and `feature?(:web3)` into the render would delete the
|
|
297
|
+
button from the DOM on a web3-off app that bundles the gem — and the "or"
|
|
298
|
+
divider reads `methodOn('wallet')` too, so ticking Solana Wallet on the style
|
|
299
|
+
guide's Sign in card would then float a divider above a button that is not
|
|
300
|
+
there.
|
|
301
|
+
|
|
302
|
+
A contributed partial renders inside the modal's own Alpine scope, so it may use
|
|
303
|
+
`methodOn(...)`, `attested()` (the legal-age gate — call it, or wallet becomes
|
|
304
|
+
the one credential that skips attestation) and `props.submitting`. It receives
|
|
305
|
+
one local, `modal_store`: the engine's real host is `"modals"`, the living style
|
|
306
|
+
guide's page-scoped host is `"dsModals"`.
|
|
307
|
+
|
|
260
308
|
It also keeps two blocks the gem renders **by name** across the gem boundary:
|
|
261
309
|
`studio/modals/blocks/wallet_brand_sprite` and `studio/modals/blocks/card_header`.
|
|
262
310
|
Renaming either is a cross-repo change.
|
|
@@ -18,26 +18,69 @@
|
|
|
18
18
|
No real auth happens — the demo shows the real UI.
|
|
19
19
|
|
|
20
20
|
LOCALS:
|
|
21
|
-
web3_gem (Boolean, required) — does solana-studio resolve
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
on purpose: a caller that forgets it should fail loudly here rather than
|
|
21
|
+
web3_gem (Boolean, required) — does solana-studio resolve, meaning is the
|
|
22
|
+
wallet-connect picker on the view path. style/_modals owns the lookup and
|
|
23
|
+
registers wallet-connect behind the same flag. Fetched without a default on
|
|
24
|
+
purpose: a caller that forgets it should fail loudly here rather than
|
|
26
25
|
silently drop Solana sign-in from an app that has the gem.
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
app
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
THE CREDENTIAL SLOT. Google and magic-link are implemented by this engine, so
|
|
28
|
+
they render below directly. Wallet is not: it belongs to the web3 bolt-on, and
|
|
29
|
+
a base-template app — a newsletter, a hub — must not carry markup it can never
|
|
30
|
+
render. So the wallet button is CONTRIBUTED by whichever layer implements it,
|
|
31
|
+
as a partial this file merely looks for:
|
|
32
|
+
|
|
33
|
+
solana_studio/auth/wallet_credential
|
|
34
|
+
|
|
35
|
+
Bundling the gem IS the registration. An app without that layer renders
|
|
36
|
+
nothing here and carries no wallet markup at all, rather than shipping a
|
|
37
|
+
button hidden behind a flag.
|
|
38
|
+
|
|
39
|
+
TWO LAYERS ANSWER TWO DIFFERENT QUESTIONS, and they are deliberately NOT
|
|
40
|
+
merged into one:
|
|
41
|
+
|
|
42
|
+
Ruby, below IS IT IMPLEMENTED. Is the picker this button swaps to
|
|
43
|
+
registered (web3_gem), and does a layer actually ship the
|
|
44
|
+
credential partial. This gates the RENDER.
|
|
45
|
+
Alpine, in the SHOULD IT SHOW. methodOn('wallet'), which reads
|
|
46
|
+
contributed props.methods first so the Sign in card's toggle overrides
|
|
47
|
+
partial the server default outright. This gates VISIBILITY.
|
|
48
|
+
|
|
49
|
+
KEEPING POLICY OUT OF THE RUBY GATE IS LOAD-BEARING, and it is why
|
|
50
|
+
auth_method?(:wallet) and feature?(:web3) are NOT terms in the render gate.
|
|
51
|
+
Fold them in and the button leaves the DOM on a web3-off app that bundles the
|
|
52
|
+
gem — and then ticking Solana Wallet on the Sign in card turns the divider
|
|
53
|
+
below on above a button that is not there, because the divider reads
|
|
54
|
+
methodOn('wallet') too. Measured: that is the exact failure this slot was
|
|
55
|
+
meant to remove, reintroduced one layer up.
|
|
56
|
+
|
|
57
|
+
NOT gated on the slot, deliberately: _methodDefaults.wallet below. It stays
|
|
58
|
+
the app's own policy answer and is unchanged by the move. It is the fallback
|
|
59
|
+
methodOn uses when an opener passes no methods hash, and on a base app nothing
|
|
60
|
+
reaches it — the Sign in card always passes explicit booleans, and the only
|
|
61
|
+
opener that omits them is the wallet picker's back button, which needs the gem
|
|
62
|
+
to exist at all.
|
|
35
63
|
|
|
36
64
|
CRITICAL: rendered inside <template x-if="id==='auth'"> — Alpine requires a
|
|
37
65
|
SINGLE root, so everything lives inside the outer <div>. The x-data is a
|
|
38
66
|
double-quoted attribute: keep it free of double-quotes and backticks.
|
|
39
67
|
%>
|
|
40
68
|
<% web3_gem = local_assigns.fetch(:web3_gem) %>
|
|
69
|
+
<%# BOTH terms are load-bearing, and they fail differently.
|
|
70
|
+
|
|
71
|
+
web3_gem is the picker this button swaps to actually REGISTERED. A layer
|
|
72
|
+
that ships the credential partial without the picker draws a button that
|
|
73
|
+
opens an empty panel — not hypothetical: solana-studio 0.5.2 shipped
|
|
74
|
+
exactly that pair, the credential without wallet_connect.
|
|
75
|
+
exists? does a layer ship the button AT ALL. Without it, an app whose
|
|
76
|
+
picker resolves but whose credential does not raises Missing partial in
|
|
77
|
+
front of someone signing in, instead of rendering no button.
|
|
78
|
+
|
|
79
|
+
Same three-term lookup_context.exists? the modal host uses for host_extras
|
|
80
|
+
(studio/modals/_host.html.erb): name, prefixes, partial. %>
|
|
81
|
+
<% wallet_credential = "solana_studio/auth/wallet_credential" %>
|
|
82
|
+
<% wallet_credential_available = web3_gem &&
|
|
83
|
+
lookup_context.exists?("wallet_credential", ["solana_studio/auth"], true) %>
|
|
41
84
|
<div x-data="{
|
|
42
85
|
email: '',
|
|
43
86
|
ageAttested: false,
|
|
@@ -85,10 +128,6 @@
|
|
|
85
128
|
if (pp) pp.submitting = null;
|
|
86
129
|
}, 1200);
|
|
87
130
|
},
|
|
88
|
-
openWalletHub() {
|
|
89
|
-
if (!this.attested()) return;
|
|
90
|
-
Alpine.store('dsModals').swap('wallet-connect', { backTo: 'auth', ageAttested: true });
|
|
91
|
-
},
|
|
92
131
|
async submitMagicLink() {
|
|
93
132
|
if (!this.attested()) return;
|
|
94
133
|
var p = this.props;
|
|
@@ -184,35 +223,19 @@
|
|
|
184
223
|
<p role="alert" class="text-red-400 text-xs -mt-2 mb-3" x-text="props.googleError"></p>
|
|
185
224
|
</template>
|
|
186
225
|
|
|
187
|
-
<%# 2.
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
server default outright.
|
|
194
|
-
Ruby web3_gem CAPABILITY — does solana-studio resolve, so
|
|
195
|
-
that something actually REGISTERED the wallet-connect id this button
|
|
196
|
-
swaps to. style/_modals wraps that registration in the same gate.
|
|
226
|
+
<%# 2. Wallet — CONTRIBUTED, not written here. See the credential-slot note
|
|
227
|
+
at the top of this file. The partial owns the button, its brand mark
|
|
228
|
+
and its click handler; this engine owns only the decision to look for
|
|
229
|
+
it. An app with no web3 layer on its view path renders nothing at all
|
|
230
|
+
here, which is the whole point: the base template ships no wallet
|
|
231
|
+
markup.
|
|
197
232
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
<% if
|
|
203
|
-
|
|
204
|
-
class="btn btn-neutral btn-lg w-full gap-3 mb-3 disabled:cursor-wait">
|
|
205
|
-
<svg width="18" height="14" viewBox="0 0 397 311" fill="none" x-show="props.submitting !== 'wallet'" aria-hidden="true">
|
|
206
|
-
<defs><linearGradient id="auth-solana-grad" x1="361" y1="-9" x2="153" y2="389" gradientUnits="userSpaceOnUse">
|
|
207
|
-
<stop offset="0" stop-color="#00FFA3"/><stop offset="1" stop-color="#DC1FFF"/>
|
|
208
|
-
</linearGradient></defs>
|
|
209
|
-
<path d="M65 234c2-2 6-4 9-4h317c6 0 9 7 5 11l-63 63c-2 2-6 4-9 4H6c-6 0-9-7-5-11l64-63z" fill="url(#auth-solana-grad)"/>
|
|
210
|
-
<path d="M65 4c2-2 6-4 9-4h317c6 0 9 7 5 11l-63 63c-2 2-6 4-9 4H6c-6 0-9-7-5-11L65 4z" fill="url(#auth-solana-grad)"/>
|
|
211
|
-
<path d="M333 119c-2-2-6-4-9-4H7c-6 0-9 7-5 11l63 63c2 2 6 4 9 4h317c6 0 9-7 5-11l-63-63z" fill="url(#auth-solana-grad)"/>
|
|
212
|
-
</svg>
|
|
213
|
-
<span x-show="props.submitting === 'wallet'" class="spinner" aria-hidden="true"></span>
|
|
214
|
-
<span x-text="props.submitting === 'wallet' ? 'Connecting…' : 'Solana'"></span>
|
|
215
|
-
</button>
|
|
233
|
+
Visibility is still Alpine's. The contributed partial carries
|
|
234
|
+
x-show methodOn('wallet'), so the Sign in card's toggle drives it
|
|
235
|
+
exactly as it drove the button that used to live here, and the divider
|
|
236
|
+
below can never float above a button the DOM is missing. %>
|
|
237
|
+
<% if wallet_credential_available %>
|
|
238
|
+
<%= render wallet_credential, modal_store: "dsModals" %>
|
|
216
239
|
<% end %>
|
|
217
240
|
|
|
218
241
|
<%# "or" divider — only when magic-link AND a social method are both on. %>
|
data/lib/studio/version.rb
CHANGED