Studio and stack-demo: forward the host's engine and token too
Extending the composite embed fix to the two remaining composites that a partner
can mount, plus two red gates that arrived on main.
plugin-studio already threaded tk, tokenUrl, locale and treeBase into every pane
it mounts — but not `provider`, so a studio embedded with provider=maplibre
showed mapbox panes and, on a keyless host, panes asking for a token. It now
forwards the engine the same way, validated to the two known values, and accepts
it as an attribute as well (a host showing plugins to partners wants to flip both
at once).
stack-demo declared no props at all, the same hole the two shipped composites
had: <stack-demo profile-config='{"tk":"…"}'> had its token read by nobody, and
on a page with no baked token the nested dashboard reported "No Mapbox access
token provided". It now parses the host config, publishes the token page-wide and
threads tk + provider into the child it mounts by tag.
MEASURED on a foreign origin, minimal config: stack-demo [tk] canvas 1 with 13
api.mapbox.com requests; stack-demo [provider] canvas 1 with ZERO. plugin-studio
[tk] canvas 1 with 19.
★ ONE LEVEL DEEPER, NOT MINE, MEASURED AND REPORTED: plugin-studio still shows
mapbox tiles under provider=maplibre, and the pane chain says why — the studio
hands provider=maplibre to <doxa-maps-spa> correctly, and the SPA then mounts
<dashboard-plus-grid> with a config carrying tk and NO provider. The cap-5 shell
drops it. Same three lines fix it there; routed to its owner rather than reached
into.
Also fixed two gates that were red on main and blocking every builder:
check:script-flags check:gallery-embed advertised --mode/--only in an
inline comment its command ends with, so the flags
could never arrive and the gate would run its default
and exit 0 looking like success. Gave the modes their
own entries and stopped the parent advertising what it
cannot receive.
check:capability-exemplars the generated table had drifted from the manifest
(a legacy bundle arrived); regenerated, 35 rows match.
This commit is contained in:
parent
e565c58ca0
commit
4727005aba
12 changed files with 77 additions and 30 deletions
|
|
@ -63,7 +63,6 @@ Generated from 22 bundle(s).
|
|||
| `doxa-simple-map` | `doxa-simple-map` | `parameterized` |
|
||||
| `doxa-vision-card` | `doxa-vision-card` | `parameterized` |
|
||||
| `people-groups-grid` | `people-groups-grid` | `parameterized` |
|
||||
| `upg-neighbor` | `upg-neighbor` | `parameterized` |
|
||||
|
||||
## Capability 3 — multi-view-element (monolithic)
|
||||
|
||||
|
|
@ -71,6 +70,7 @@ Generated from 22 bundle(s).
|
|||
|---|---|---|
|
||||
| `doxa-research-map` | `research-map` | `monolithic` |
|
||||
| `research-dashboard` | `research-dashboard` | `monolithic` |
|
||||
| `upg-neighbor` | `upg-neighbor` | `monolithic` |
|
||||
|
||||
## Capability 4 — composite-element (nested-element SPA)
|
||||
|
||||
|
|
|
|||
|
|
@ -146,7 +146,9 @@
|
|||
"check:synced-css": "node internal/check-synced-css-copies.mjs",
|
||||
"check:composite-reg": "node internal/check-composite-registration.mjs",
|
||||
"check:filter-width": "node internal/check-filter-width-stable.mjs",
|
||||
"check:gallery-embed": "node internal/check-research-gallery-embed.mjs # the cap-5 Research Gallery must embed on a FOREIGN ORIGIN (a stand-in host page on localhost, the built tree on 127.0.0.1) in BOTH modes — bare <script>+<doxa-maps-spa> and <iframe> — with the layout inside the host box and every curated tab painting a map. Starts its own servers on OS-assigned ports; needs only a built tree. --mode js|iframe, --only <tab,tab>. Exit 2 = SKIP (no built tree / no playwright).",
|
||||
"check:gallery-embed": "node internal/check-research-gallery-embed.mjs # the cap-5 Research Gallery must embed on a FOREIGN ORIGIN (a stand-in host page on localhost, the built tree on 127.0.0.1) in BOTH modes — bare <script>+<doxa-maps-spa> and <iframe> — with the layout inside the host box and every curated tab painting a map. Starts its own servers on OS-assigned ports; needs only a built tree. Runs both modes; for one mode use the sibling entries check:gallery-embed:js and check:gallery-embed:iframe, and to narrow to specific tabs invoke internal/check-research-gallery-embed.mjs directly. Naming the flags HERE made check:script-flags red: this command ends in a # comment, so anything appended lands inside the comment and the shell drops it, and the gate would run its default and exit 0 looking like success. Exit 2 = SKIP (no built tree / no playwright).",
|
||||
"check:gallery-embed:js": "node internal/check-research-gallery-embed.mjs --mode js # the JS-embed half of check:gallery-embed, as its own entry. The flag cannot reach the gate through `bun run check:gallery-embed --mode js`: that script ends in an inline # comment, so the shell drops anything appended after it and the gate silently runs its default and exits 0 — check:script-flags exists for exactly that trap.",
|
||||
"check:gallery-embed:iframe": "node internal/check-research-gallery-embed.mjs --mode iframe # the iframe half, same reason.",
|
||||
"check:spa-tab-order": "node internal/check-spa-tab-order.mjs # the cap-5 SPA must open on Big Picture and keep the Driver's order (Big Picture, UPG-100, Prayer Progress, Gospel Resources) — asserted as PRESENCE + tab-1 + RELATIVE order on the RENDERED rail, because the rail gained three sections and now renders 12 rows with others between them. ⚠ NOT WAVE-WIRED: it FAILS rather than skips when the SPA is unreachable, deliberately (\"a gate that cannot reach its subject has not passed, it has not run\") — correct standalone, but gates:post runs on checkouts with no server. Needs `bun run serve` on 4173.",
|
||||
"check:backlog-status": "node internal/check-backlog-status-enum.mjs",
|
||||
"check:mjs-parse": "node internal/check-mjs-parses.mjs",
|
||||
|
|
|
|||
|
|
@ -382,6 +382,10 @@ export default defineComponent({
|
|||
props: {
|
||||
treeBase: { type: String, default: '' },
|
||||
profileConfig: { type: [String, Object], default: '' },
|
||||
// The map engine, as an attribute as well as a profile-config key — the studio previews map
|
||||
// plugins, so a host showing it to partners wants to flip both at once. Forwarded to every pane
|
||||
// below; an unrecognised value is ignored there rather than passed on.
|
||||
provider: { type: String, default: '' },
|
||||
// NOT `title` — that name collides with the NATIVE HTMLElement.title property.
|
||||
// defineCustomElement maps every prop to an attribute, and `title` already exists on every
|
||||
// element (the tooltip), so Vue warned on EVERY mount:
|
||||
|
|
@ -875,6 +879,13 @@ export default defineComponent({
|
|||
const pc = { profile: row.label, instanceId: 'ps-' + row.key.replace(/\//g, '-'), locale: this.locale }
|
||||
if (this.tk || this.cfg.tk) pc.tk = this.tk || this.cfg.tk
|
||||
if (this.tokenUrl || this.cfg.tokenUrl) pc.tokenUrl = this.tokenUrl || this.cfg.tokenUrl
|
||||
// ★ AND THE ENGINE, for the same reason tk rides along. resolveMapProvider's ladder starts
|
||||
// at profile-config.provider, and a pane reads the config THIS file writes — so a studio
|
||||
// embedded with provider=maplibre showed mapbox panes and, on a keyless host, panes that
|
||||
// asked for a token. MEASURED on a foreign origin: 19 requests to api.mapbox.com for a
|
||||
// maplibre request. Validated to the two known engines so a typo cannot select a third.
|
||||
const wantProvider = this.provider || this.cfg.provider
|
||||
if (wantProvider === 'maplibre' || wantProvider === 'mapbox') pc.provider = wantProvider
|
||||
// PASS THE TREE BASE DOWN — a nested cap-5 shell cannot guess it.
|
||||
// doxa-maps-spa carries its OWN hardcoded, TREE-RELATIVE tab list (doxa-maps-spa.vue:265-312,
|
||||
// e.g. 'doxa-research-map/research-map/index.html') and resolves it against ITS treeBase,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@
|
|||
* layouts in library/layouts/. StackLayout mounts each section's `element` eagerly (all visible to
|
||||
* scroll) via the same element/src/attrs contract VerticalTabsLayout uses.
|
||||
*/
|
||||
import { computed } from 'vue'
|
||||
import StackLayout from '@map/layouts/StackLayout.vue'
|
||||
import { publishMapToken } from '@map/composables/useSharedMapToken.js'
|
||||
|
||||
// The two elements to stack. `src` is TREE-RELATIVE at build; the leaf pages resolve it against the
|
||||
// bundle tree root. Both elements ship their own bundles in the same catalog.
|
||||
|
|
@ -42,7 +44,30 @@ import StackLayout from '@map/layouts/StackLayout.vue'
|
|||
const bundleSrc = (bundle, file) =>
|
||||
import.meta.env.DEV ? `/plugin-designs/${bundle}/index.js` : `../../${bundle}/${file}.js`
|
||||
|
||||
const sections = [
|
||||
// ★ THE HOST'S OWN profile-config. This demo declared no props, so a partner embedding it with
|
||||
// <stack-demo profile-config='{"tk":"pk...."}'> had that token read by nobody and the nested
|
||||
// dashboard reported "No Mapbox access token provided" on a page with no baked token to fall back
|
||||
// on. Same defect the two shipped composites had; check:composite-embed-knobs names it.
|
||||
const props = defineProps({
|
||||
profileConfig: { type: [String, Object], default: null },
|
||||
})
|
||||
const hostConfig = computed(() => {
|
||||
const raw = props.profileConfig
|
||||
if (!raw) return {}
|
||||
if (typeof raw === 'object') return raw
|
||||
try { return JSON.parse(raw) } catch { return {} }
|
||||
})
|
||||
const hostToken = computed(() => {
|
||||
const tk = hostConfig.value?.tk
|
||||
return typeof tk === 'string' && tk ? tk : ''
|
||||
})
|
||||
if (hostToken.value) publishMapToken(hostToken.value)
|
||||
const hostProvider = computed(() => {
|
||||
const p = hostConfig.value?.provider
|
||||
return p === 'maplibre' || p === 'mapbox' ? p : ''
|
||||
})
|
||||
|
||||
const sections = computed(() => [
|
||||
{
|
||||
key: 'dashboard',
|
||||
title: 'Research Dashboard',
|
||||
|
|
@ -62,6 +87,10 @@ const sections = [
|
|||
profile: 'research-dashboard',
|
||||
dataSource: 'pray-tools',
|
||||
instanceId: 'stack-demo-research-dashboard',
|
||||
// Spread only when the host supplied one, so the nested mount otherwise asks for exactly
|
||||
// what its standalone leaf asks for.
|
||||
...(hostToken.value ? { tk: hostToken.value } : {}),
|
||||
...(hostProvider.value ? { provider: hostProvider.value } : {}),
|
||||
assetsBase: '../../assets'
|
||||
})
|
||||
}
|
||||
|
|
@ -73,7 +102,7 @@ const sections = [
|
|||
element: 'people-groups-grid',
|
||||
src: bundleSrc('people-groups-grid', 'people-groups-grid')
|
||||
}
|
||||
]
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
|||
2
public/doxa-maps/index.html
generated
2
public/doxa-maps/index.html
generated
File diff suppressed because one or more lines are too long
8
public/doxa-maps/manifest.json
generated
8
public/doxa-maps/manifest.json
generated
|
|
@ -799,7 +799,7 @@
|
|||
"bundle": "plugin-studio",
|
||||
"scriptUrl": "./plugin-studio/plugin-studio.js",
|
||||
"output": "doxa-maps/plugin-studio/plugin-studio.js",
|
||||
"integrity": "sha384-2RlLFRU2XdjBN7w+FPguj8INgj57JFg4IFT2AmdefGnR9QQLehbiiAffV45LcsFH",
|
||||
"integrity": "sha384-EvwAOYsSENxqsDaAJcyANtACSyVvdFI7Eh3BiB4dHIFjln2tqx+G/VUpLC1zurMO",
|
||||
"elements": [
|
||||
"plugin-studio"
|
||||
],
|
||||
|
|
@ -827,7 +827,7 @@
|
|||
"scriptUrl": "./plugin-studio/plugin-studio.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./plugin-studio/plugin-studio/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./plugin-studio/plugin-studio.js\" integrity=\"sha384-2RlLFRU2XdjBN7w+FPguj8INgj57JFg4IFT2AmdefGnR9QQLehbiiAffV45LcsFH\" crossorigin=\"anonymous\"></script>\n<plugin-studio profile-config='{\"profile\":\"plugin-studio\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></plugin-studio>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./plugin-studio/plugin-studio.js\" integrity=\"sha384-EvwAOYsSENxqsDaAJcyANtACSyVvdFI7Eh3BiB4dHIFjln2tqx+G/VUpLC1zurMO\" crossorigin=\"anonymous\"></script>\n<plugin-studio profile-config='{\"profile\":\"plugin-studio\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></plugin-studio>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
@ -1006,7 +1006,7 @@
|
|||
"bundle": "stack-demo",
|
||||
"scriptUrl": "./stack-demo/stack-demo.js",
|
||||
"output": "doxa-maps/stack-demo/stack-demo.js",
|
||||
"integrity": "sha384-gnwM6s+puf1K60Nl7crQcC2QC+9BxwpkaTx4OepLZ8VUCraZc+aRlWpsb6nj6Gyf",
|
||||
"integrity": "sha384-EI3V6JX9ws4fGxKBzMOgwhG5de8MvL6va3zqmB2gTXecd/m0mxNq8eUht/SGzH1B",
|
||||
"elements": [
|
||||
"stack-demo"
|
||||
],
|
||||
|
|
@ -1026,7 +1026,7 @@
|
|||
"scriptUrl": "./stack-demo/stack-demo.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./stack-demo/stack-demo/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./stack-demo/stack-demo.js\" integrity=\"sha384-gnwM6s+puf1K60Nl7crQcC2QC+9BxwpkaTx4OepLZ8VUCraZc+aRlWpsb6nj6Gyf\" crossorigin=\"anonymous\"></script>\n<stack-demo profile-config='{\"profile\":\"stack-demo\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></stack-demo>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./stack-demo/stack-demo.js\" integrity=\"sha384-EI3V6JX9ws4fGxKBzMOgwhG5de8MvL6va3zqmB2gTXecd/m0mxNq8eUht/SGzH1B\" crossorigin=\"anonymous\"></script>\n<stack-demo profile-config='{\"profile\":\"stack-demo\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></stack-demo>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
|
|||
23
public/doxa-maps/plugin-studio/plugin-studio.js
generated
23
public/doxa-maps/plugin-studio/plugin-studio.js
generated
File diff suppressed because one or more lines are too long
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <plugin-studio> custom element. -->
|
||||
<script src="../plugin-studio.js" integrity="sha384-2RlLFRU2XdjBN7w+FPguj8INgj57JFg4IFT2AmdefGnR9QQLehbiiAffV45LcsFH" crossorigin="anonymous"></script>
|
||||
<script src="../plugin-studio.js" integrity="sha384-EvwAOYsSENxqsDaAJcyANtACSyVvdFI7Eh3BiB4dHIFjln2tqx+G/VUpLC1zurMO" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <plugin-studio> custom element. -->
|
||||
<script src="../../plugin-studio.js" integrity="sha384-2RlLFRU2XdjBN7w+FPguj8INgj57JFg4IFT2AmdefGnR9QQLehbiiAffV45LcsFH" crossorigin="anonymous"></script>
|
||||
<script src="../../plugin-studio.js" integrity="sha384-EvwAOYsSENxqsDaAJcyANtACSyVvdFI7Eh3BiB4dHIFjln2tqx+G/VUpLC1zurMO" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
16
public/doxa-maps/stack-demo/stack-demo.js
generated
16
public/doxa-maps/stack-demo/stack-demo.js
generated
File diff suppressed because one or more lines are too long
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <stack-demo> custom element. -->
|
||||
<script src="../stack-demo.js" integrity="sha384-gnwM6s+puf1K60Nl7crQcC2QC+9BxwpkaTx4OepLZ8VUCraZc+aRlWpsb6nj6Gyf" crossorigin="anonymous"></script>
|
||||
<script src="../stack-demo.js" integrity="sha384-EI3V6JX9ws4fGxKBzMOgwhG5de8MvL6va3zqmB2gTXecd/m0mxNq8eUht/SGzH1B" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <stack-demo> custom element. -->
|
||||
<script src="../../stack-demo.js" integrity="sha384-gnwM6s+puf1K60Nl7crQcC2QC+9BxwpkaTx4OepLZ8VUCraZc+aRlWpsb6nj6Gyf" crossorigin="anonymous"></script>
|
||||
<script src="../../stack-demo.js" integrity="sha384-EI3V6JX9ws4fGxKBzMOgwhG5de8MvL6va3zqmB2gTXecd/m0mxNq8eUht/SGzH1B" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
Loading…
Reference in a new issue