@concepttocloud/saiku-embed 3.18.2

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/README.md ADDED
@@ -0,0 +1,197 @@
1
+ # `<saiku-embed>` — Saiku Web Component
2
+
3
+ Drop a saved Saiku query or dashboard into any page on the open web. Same
4
+ tag works in React, Vue, Svelte, and vanilla HTML — it's a real
5
+ [Custom Element](https://developer.mozilla.org/docs/Web/API/Web_components),
6
+ so the host page doesn't have to know anything about Saiku internals.
7
+
8
+ ## Install
9
+
10
+ ```html
11
+ <script src="https://YOUR-SAIKU.example.com/ui/saiku-embed.js"></script>
12
+ ```
13
+
14
+ Or via npm (for React / Vue / SPA projects that bundle their own JS):
15
+
16
+ ```bash
17
+ npm install @concepttocloud/saiku-embed
18
+ ```
19
+
20
+ ```ts
21
+ import "@concepttocloud/saiku-embed";
22
+ ```
23
+
24
+ The import has the side effect of registering the `saiku-embed` tag
25
+ globally — no further setup.
26
+
27
+ ## Use
28
+
29
+ ### A saved query, rendered as a table
30
+
31
+ ```html
32
+ <saiku-embed
33
+ server="https://YOUR-SAIKU.example.com"
34
+ token="..."
35
+ path="homes/admin/Examples/Trend.saiku"
36
+ height="400px"
37
+ ></saiku-embed>
38
+ ```
39
+
40
+ ### A saved query, rendered as a bar / line / pie chart
41
+
42
+ ```html
43
+ <saiku-embed
44
+ server="..."
45
+ token="..."
46
+ path="homes/admin/Examples/Sales.saiku"
47
+ render="chart"
48
+ mode="bar"
49
+ height="500px"
50
+ ></saiku-embed>
51
+ ```
52
+
53
+ ### A saved dashboard
54
+
55
+ ```html
56
+ <saiku-embed
57
+ server="..."
58
+ token="..."
59
+ kind="dashboard"
60
+ path="homes/admin/exec.saikudash"
61
+ height="700px"
62
+ ></saiku-embed>
63
+ ```
64
+
65
+ ### Anonymous public embed
66
+
67
+ If the resource is marked publicly embeddable on the server
68
+ (see "Public grants" below), omit the token entirely:
69
+
70
+ ```html
71
+ <saiku-embed
72
+ server="..."
73
+ path="shared/public-chart.saiku"
74
+ render="chart"
75
+ ></saiku-embed>
76
+ ```
77
+
78
+ ## Attributes
79
+
80
+ | Attribute | Default | Notes |
81
+ |-----------|-------------|------------------------------------------------------------------------|
82
+ | `server` | _(required)_| Origin of the Saiku launcher, e.g. `https://demo.saiku.bi` |
83
+ | `path` | _(required)_| Repository path of the saved query (`.saiku`) or dashboard (`.saikudash`) |
84
+ | `kind` | `query` | `query` or `dashboard` |
85
+ | `token` | _(none)_ | Embed token from `POST /saiku/api/embed/tokens`. Omit for public reads |
86
+ | `render` | `table` | For `kind=query`: `table` or `chart` |
87
+ | `mode` | `bar` | For `render=chart`: `bar`, `line`, or `pie` |
88
+ | `height` | `400px` | CSS height of the rendered surface |
89
+
90
+ The component re-renders whenever an attribute changes, so frameworks
91
+ binding state to attrs (React's JSX, Vue's `:server="..."`, etc.) just
92
+ work.
93
+
94
+ ## Server-side: minting a token
95
+
96
+ Authenticated as a user who has GRANT on the saved query / dashboard:
97
+
98
+ ```bash
99
+ curl -X POST 'https://YOUR-SAIKU/rest/saiku/api/embed/tokens' \
100
+ -u admin:admin \
101
+ -H 'Content-Type: application/json' \
102
+ -d '{
103
+ "resourceKind": "query",
104
+ "resourcePath": "homes/admin/Examples/Trend.saiku",
105
+ "ttlHours": 72,
106
+ "label": "Marketing landing page"
107
+ }'
108
+ # → { "status": "OK", "token": "tx-...", "expiresAt": ... }
109
+ ```
110
+
111
+ Paste the `token` into the host page's `<saiku-embed token="...">`.
112
+ Tokens are server-authoritative — revoke any time via:
113
+
114
+ ```bash
115
+ curl -X DELETE 'https://YOUR-SAIKU/rest/saiku/api/embed/tokens/<token>' \
116
+ -u admin:admin
117
+ ```
118
+
119
+ ## Server-side: public grants
120
+
121
+ To make a resource readable WITHOUT a token (e.g. for a public blog post):
122
+
123
+ ```bash
124
+ curl -X POST 'https://YOUR-SAIKU/rest/saiku/api/embed/public' \
125
+ -u admin:admin \
126
+ -H 'Content-Type: application/json' \
127
+ -d '{
128
+ "resourceKind": "query",
129
+ "resourcePath": "shared/public-chart.saiku",
130
+ "label": "Homepage chart"
131
+ }'
132
+ ```
133
+
134
+ Public reads still run under the grantor's data scope, so any
135
+ session-injected filters render from the grantor's perspective.
136
+ Revoke:
137
+
138
+ ```bash
139
+ curl -X DELETE 'https://YOUR-SAIKU/rest/saiku/api/embed/public?kind=query&path=shared/public-chart.saiku' \
140
+ -u admin:admin
141
+ ```
142
+
143
+ ## Styling
144
+
145
+ The embed lives inside an
146
+ [open shadow root](https://developer.mozilla.org/docs/Web/API/ShadowRoot),
147
+ so host page CSS can't leak in and vice versa. To recolour the embed,
148
+ set CSS variables on the host page:
149
+
150
+ ```css
151
+ saiku-embed {
152
+ --saiku-embed-fg: #0f172a;
153
+ --saiku-embed-bg: transparent;
154
+ --saiku-embed-border: #cbd5e1;
155
+ --saiku-embed-header-bg: #f1f5f9;
156
+ --saiku-embed-tile-bg: #ffffff;
157
+ --saiku-embed-row-hover: #e2e8f0;
158
+ --saiku-embed-negative: #b91c1c;
159
+ --saiku-embed-error: #b91c1c;
160
+ --saiku-embed-muted: #64748b;
161
+ }
162
+ ```
163
+
164
+ ## Security model
165
+
166
+ - **Header-only token transport.** The token travels as
167
+ `X-Saiku-Embed-Token`. Never a `?token=` query parameter — those leak
168
+ into access logs, proxy logs, browser history, and outbound
169
+ `Referer`.
170
+ - **Server-side authoritative.** Tokens are opaque random 256-bit ids
171
+ with no embedded claims; the server looks them up on every request.
172
+ Revocation takes effect on the very next request.
173
+ - **Per-resource scope.** A token pins exactly one query or dashboard.
174
+ Replaying it against any other resource (or any other endpoint)
175
+ returns the same opaque `EMBED_INVALID` 401, regardless of whether
176
+ the request used the wrong kind, the wrong path, an expired token,
177
+ or a revoked one. Probes can't enumerate.
178
+ - **Cross-origin cookie isolation.** The embed sends
179
+ `credentials: "omit"`, so the host page's Saiku session cookie (if
180
+ the user happens to be logged in) doesn't flow with embed reads.
181
+ The token IS the only auth carrier on this surface.
182
+
183
+ ## Bundle size
184
+
185
+ Around **213 KB gzipped** at the time of writing — Svelte 5 custom
186
+ element runtime + ECharts (core + bar / line / pie + four common
187
+ components, modular tree-shaken) + the embed renderers.
188
+
189
+ ## Limitations
190
+
191
+ - Records-format only. The matrix format isn't rendered in v1.
192
+ - Dashboard `filter` tiles are skipped — the embed renders the
193
+ authored data as-is without an interactive filter bar.
194
+ - Markdown in `text` tiles renders as plain text (no `marked`
195
+ dependency to keep the bundle tight).
196
+ - AI Query results (`/ai/query`) aren't wired as an `<saiku-embed>`
197
+ source yet — coming in a follow-up.
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@concepttocloud/saiku-embed",
3
+ "version": "3.18.2",
4
+ "description": "<saiku-embed> Web Component — drop a saved Saiku query or dashboard into any page.",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "main": "./saiku-embed.js",
8
+ "files": [
9
+ "saiku-embed.js",
10
+ "saiku-embed.js.map",
11
+ "README.md"
12
+ ],
13
+ "keywords": [
14
+ "saiku",
15
+ "olap",
16
+ "embed",
17
+ "web-component",
18
+ "custom-element",
19
+ "dashboard",
20
+ "chart"
21
+ ],
22
+ "homepage": "https://github.com/spiculedata/saiku",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/spiculedata/saiku.git",
26
+ "directory": "saiku-ui/src/embed"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/spiculedata/saiku/issues"
30
+ }
31
+ }