@bridgeline-digital/hawk-app-bridge 0.1.0-dev.20261020202308 → 0.1.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.
- package/LICENSE +7 -7
- package/PROTOCOL.md +81 -81
- package/README.md +1315 -1315
- package/dist/host/app-checks.js +25 -25
- package/dist/host/app-icon.js +7 -7
- package/dist/host/app-slot.js +34 -34
- package/package.json +1 -1
package/LICENSE
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
Copyright (c) 2026 Bridgeline Digital, Inc. All rights reserved.
|
|
2
|
-
|
|
3
|
-
This software is proprietary to Bridgeline Digital, Inc. It is published for use by Bridgeline Digital
|
|
4
|
-
and its authorized developers with the Hawk Apps platform. No license is granted to copy, modify, distribute,
|
|
5
|
-
sublicense or use it for any other purpose without Bridgeline Digital's prior written permission.
|
|
6
|
-
|
|
7
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.
|
|
1
|
+
Copyright (c) 2026 Bridgeline Digital, Inc. All rights reserved.
|
|
2
|
+
|
|
3
|
+
This software is proprietary to Bridgeline Digital, Inc. It is published for use by Bridgeline Digital
|
|
4
|
+
and its authorized developers with the Hawk Apps platform. No license is granted to copy, modify, distribute,
|
|
5
|
+
sublicense or use it for any other purpose without Bridgeline Digital's prior written permission.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.
|
package/PROTOCOL.md
CHANGED
|
@@ -1,81 +1,81 @@
|
|
|
1
|
-
# @bridgeline-digital/hawk-app-bridge protocol v1
|
|
2
|
-
|
|
3
|
-
This is the contract between a **host** (the HawkSearch dashboard) and an embedded **app**. A new host is compatible once it meets the "Host requirements" section below. Apps never depend on anything outside this document.
|
|
4
|
-
|
|
5
|
-
## Transport
|
|
6
|
-
|
|
7
|
-
- `window.postMessage` between the host page and the app iframe.
|
|
8
|
-
- The host appends `hawkHost=<host origin>` to the app URL. The app sends only to that origin. Which hosts may embed an app is enforced by the apps CDN (`frame-ancestors`, see below), so apps don't list host origins themselves (`allowedHostOrigins` remains as an optional extra check).
|
|
9
|
-
- Both sides **must** check `event.source` (the expected window) **and** `event.origin` (the expected origin) before acting on a message. Each side posts with an explicit target origin, never `"*"`.
|
|
10
|
-
|
|
11
|
-
## Envelope
|
|
12
|
-
|
|
13
|
-
```jsonc
|
|
14
|
-
{
|
|
15
|
-
"source": "hawk-app-bridge",
|
|
16
|
-
"type": "hawk:app:v1:<name>", // requests and events; responses use "hawk:app:v1:response"
|
|
17
|
-
"id": "<uuid>", // requests only
|
|
18
|
-
"replyTo": "<request id>", // responses only
|
|
19
|
-
"payload": { },
|
|
20
|
-
"error": { "code": "<code>", "message": "..." } // failed responses only
|
|
21
|
-
}
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
Error codes: `unsupported`, `handler_error`, `timeout`, `protocol_mismatch`, `not_ready`, `not_embedded`, `no_host`, `host_not_allowed`, `destroyed`.
|
|
25
|
-
|
|
26
|
-
## Requests (app → host)
|
|
27
|
-
|
|
28
|
-
| name | payload | result |
|
|
29
|
-
|---|---|---|
|
|
30
|
-
| `init` | `{ sdkVersion, minProtocolVersion }` | `HawkAppContext`. Must be the first request; the host answers `not_ready` to anything sent before it. |
|
|
31
|
-
| `getContext` | — | `HawkAppContext` |
|
|
32
|
-
| `getToken` | `{ forceRefresh }` | `{ token, expiresAt }` (ISO-8601) |
|
|
33
|
-
| `navigate` | `NavigationIntent` | — |
|
|
34
|
-
| `toast` | `{ message, variant: info\|success\|warning\|error }` | — |
|
|
35
|
-
| `setTitle` | `{ title }` | — |
|
|
36
|
-
| `resize` | `{ height }` (px) | — |
|
|
37
|
-
|
|
38
|
-
## Events (host → app)
|
|
39
|
-
|
|
40
|
-
| name | payload | when |
|
|
41
|
-
|---|---|---|
|
|
42
|
-
| `contextChanged` | `HawkAppContext` | site, engine, date range, theme or locale changed. Only sent after `init`. |
|
|
43
|
-
|
|
44
|
-
## Context
|
|
45
|
-
|
|
46
|
-
```ts
|
|
47
|
-
{
|
|
48
|
-
protocolVersion: 1,
|
|
49
|
-
app: { slug },
|
|
50
|
-
tenant: { clientId, accountId? },
|
|
51
|
-
user: { id, email?, roles[] },
|
|
52
|
-
site?: { id, name? } | null,
|
|
53
|
-
engine?: { id, name? } | null,
|
|
54
|
-
dateRange?: { from, to, timeZone? } | null, // ISO-8601
|
|
55
|
-
locale: "en-US",
|
|
56
|
-
theme?: { mode: "light" | "dark", tokens: { "<token>": "<css value>" } } | null,
|
|
57
|
-
apiBaseUrl: "https://<platform>/v1/"
|
|
58
|
-
}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
The context carries no host-specific identifiers, routes or feature names. The tenant shown in the context is for display only. The platform takes the tenant from the signed token, never from what the app sends.
|
|
62
|
-
|
|
63
|
-
## Navigation intents
|
|
64
|
-
|
|
65
|
-
`{ intent: "app", slug, params? }`, `{ intent: "report", id }`, `{ intent: "settings", section? }`, `{ intent: "external", url }`.
|
|
66
|
-
|
|
67
|
-
Each host maps intents to its own routes. Unknown intents should be rejected with `unsupported`.
|
|
68
|
-
|
|
69
|
-
## Host requirements (the adapter the HawkSearch dashboard and Spark each implement)
|
|
70
|
-
|
|
71
|
-
1. **Render** `<hawk-app-frame src="<manifest.entryUrl>">` from `@bridgeline-digital/hawk-app-bridge/host`, keeping the default sandbox.
|
|
72
|
-
2. **Context:** set `element.context` once the host session is known, and again whenever it changes.
|
|
73
|
-
3. **Token:** set `element.tokenProvider`. It calls the host backend endpoint `POST /api/apps/{slug}/token`. That endpoint authenticates the user's session, then calls the platform's `/token/exchange` server-to-server using the host's own credential, and returns `{ token, expiresAt }`. Tokens are never minted in the browser.
|
|
74
|
-
4. **Events:** handle `hawk-navigate` (map intents to routes) and `hawk-toast`. `hawk-title` and `hawk-resize` are optional.
|
|
75
|
-
5. **CSP:** `frame-src https://apps.<domain>`. The apps' CDN sends `frame-ancestors <registered host origins>`.
|
|
76
|
-
|
|
77
|
-
## Versioning
|
|
78
|
-
|
|
79
|
-
- Adding optional fields, requests or events is allowed within v1. Receivers must ignore unknown fields.
|
|
80
|
-
- Breaking changes need a new version and a new prefix (`hawk:app:v2:`). Hosts may support several versions side by side.
|
|
81
|
-
- Apps declare `minProtocolVersion` in `init`, and in their registry manifest.
|
|
1
|
+
# @bridgeline-digital/hawk-app-bridge protocol v1
|
|
2
|
+
|
|
3
|
+
This is the contract between a **host** (the HawkSearch dashboard) and an embedded **app**. A new host is compatible once it meets the "Host requirements" section below. Apps never depend on anything outside this document.
|
|
4
|
+
|
|
5
|
+
## Transport
|
|
6
|
+
|
|
7
|
+
- `window.postMessage` between the host page and the app iframe.
|
|
8
|
+
- The host appends `hawkHost=<host origin>` to the app URL. The app sends only to that origin. Which hosts may embed an app is enforced by the apps CDN (`frame-ancestors`, see below), so apps don't list host origins themselves (`allowedHostOrigins` remains as an optional extra check).
|
|
9
|
+
- Both sides **must** check `event.source` (the expected window) **and** `event.origin` (the expected origin) before acting on a message. Each side posts with an explicit target origin, never `"*"`.
|
|
10
|
+
|
|
11
|
+
## Envelope
|
|
12
|
+
|
|
13
|
+
```jsonc
|
|
14
|
+
{
|
|
15
|
+
"source": "hawk-app-bridge",
|
|
16
|
+
"type": "hawk:app:v1:<name>", // requests and events; responses use "hawk:app:v1:response"
|
|
17
|
+
"id": "<uuid>", // requests only
|
|
18
|
+
"replyTo": "<request id>", // responses only
|
|
19
|
+
"payload": { },
|
|
20
|
+
"error": { "code": "<code>", "message": "..." } // failed responses only
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Error codes: `unsupported`, `handler_error`, `timeout`, `protocol_mismatch`, `not_ready`, `not_embedded`, `no_host`, `host_not_allowed`, `destroyed`.
|
|
25
|
+
|
|
26
|
+
## Requests (app → host)
|
|
27
|
+
|
|
28
|
+
| name | payload | result |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| `init` | `{ sdkVersion, minProtocolVersion }` | `HawkAppContext`. Must be the first request; the host answers `not_ready` to anything sent before it. |
|
|
31
|
+
| `getContext` | — | `HawkAppContext` |
|
|
32
|
+
| `getToken` | `{ forceRefresh }` | `{ token, expiresAt }` (ISO-8601) |
|
|
33
|
+
| `navigate` | `NavigationIntent` | — |
|
|
34
|
+
| `toast` | `{ message, variant: info\|success\|warning\|error }` | — |
|
|
35
|
+
| `setTitle` | `{ title }` | — |
|
|
36
|
+
| `resize` | `{ height }` (px) | — |
|
|
37
|
+
|
|
38
|
+
## Events (host → app)
|
|
39
|
+
|
|
40
|
+
| name | payload | when |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| `contextChanged` | `HawkAppContext` | site, engine, date range, theme or locale changed. Only sent after `init`. |
|
|
43
|
+
|
|
44
|
+
## Context
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
{
|
|
48
|
+
protocolVersion: 1,
|
|
49
|
+
app: { slug },
|
|
50
|
+
tenant: { clientId, accountId? },
|
|
51
|
+
user: { id, email?, roles[] },
|
|
52
|
+
site?: { id, name? } | null,
|
|
53
|
+
engine?: { id, name? } | null,
|
|
54
|
+
dateRange?: { from, to, timeZone? } | null, // ISO-8601
|
|
55
|
+
locale: "en-US",
|
|
56
|
+
theme?: { mode: "light" | "dark", tokens: { "<token>": "<css value>" } } | null,
|
|
57
|
+
apiBaseUrl: "https://<platform>/v1/"
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The context carries no host-specific identifiers, routes or feature names. The tenant shown in the context is for display only. The platform takes the tenant from the signed token, never from what the app sends.
|
|
62
|
+
|
|
63
|
+
## Navigation intents
|
|
64
|
+
|
|
65
|
+
`{ intent: "app", slug, params? }`, `{ intent: "report", id }`, `{ intent: "settings", section? }`, `{ intent: "external", url }`.
|
|
66
|
+
|
|
67
|
+
Each host maps intents to its own routes. Unknown intents should be rejected with `unsupported`.
|
|
68
|
+
|
|
69
|
+
## Host requirements (the adapter the HawkSearch dashboard and Spark each implement)
|
|
70
|
+
|
|
71
|
+
1. **Render** `<hawk-app-frame src="<manifest.entryUrl>">` from `@bridgeline-digital/hawk-app-bridge/host`, keeping the default sandbox.
|
|
72
|
+
2. **Context:** set `element.context` once the host session is known, and again whenever it changes.
|
|
73
|
+
3. **Token:** set `element.tokenProvider`. It calls the host backend endpoint `POST /api/apps/{slug}/token`. That endpoint authenticates the user's session, then calls the platform's `/token/exchange` server-to-server using the host's own credential, and returns `{ token, expiresAt }`. Tokens are never minted in the browser.
|
|
74
|
+
4. **Events:** handle `hawk-navigate` (map intents to routes) and `hawk-toast`. `hawk-title` and `hawk-resize` are optional.
|
|
75
|
+
5. **CSP:** `frame-src https://apps.<domain>`. The apps' CDN sends `frame-ancestors <registered host origins>`.
|
|
76
|
+
|
|
77
|
+
## Versioning
|
|
78
|
+
|
|
79
|
+
- Adding optional fields, requests or events is allowed within v1. Receivers must ignore unknown fields.
|
|
80
|
+
- Breaking changes need a new version and a new prefix (`hawk:app:v2:`). Hosts may support several versions side by side.
|
|
81
|
+
- Apps declare `minProtocolVersion` in `init`, and in their registry manifest.
|