@port-labs/plugins-sdk 0.0.1

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,208 @@
1
+ # `@port-labs/plugins-sdk`
2
+
3
+ TypeScript/JavaScript SDK for **Port custom plugins** running inside the Port web app (usually in an iframe). For **React**, use **`usePortPluginData`** from **`@port-labs/plugins-sdk/react`**. For **other stacks**, the same host context is available via a small **subscribe / snapshot** store and synchronous **getters**. The package also helps merge dashboard page filters into Port entity-search queries (`mergePageFilters`).
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @port-labs/plugins-sdk
9
+ ```
10
+
11
+ ```bash
12
+ yarn add @port-labs/plugins-sdk
13
+ ```
14
+
15
+ ```bash
16
+ pnpm add @port-labs/plugins-sdk
17
+ ```
18
+
19
+ **Optional peer:** **react** ≥ 18 — only required if you import `@port-labs/plugins-sdk/react`.
20
+
21
+ **Node:** use an LTS version compatible with your bundler; this package declares `engines.node` ≥ 22.
22
+
23
+ ## What it does
24
+
25
+ 1. Listens for messages from the Port host (`PORT_TOKEN`, `PLUGIN_DATA`).
26
+ 2. When embedded in an iframe, asks the parent once for a token (`REQUEST_PORT_TOKEN`).
27
+ 3. Exposes the latest host payload through **`usePortPluginData`** (React) or **getters** and **`subscribe` + `getSnapshot`** (Vue, Svelte, Solid, vanilla JS, etc.).
28
+ 4. Provides **`mergePageFilters`** to combine your widget’s entity-search body with the page’s filter rules.
29
+
30
+ ## Host protocol
31
+
32
+ Your plugin and the Port UI must agree on these messages:
33
+
34
+ | Direction | `event.data.type` | Payload / role |
35
+ | ------------- | -------------------- | --------------------------------------- |
36
+ | Plugin → host | `REQUEST_PORT_TOKEN` | Ask the host for a JWT for Port API calls. |
37
+ | Host → plugin | `PORT_TOKEN` | `{ token: string }` |
38
+ | Host → plugin | `PLUGIN_DATA` | `{ params, page, user, entity, baseUrl, theme? }` |
39
+
40
+ **Getters** expose: `params`, `page`, `user`, `entity`, `theme` (via `getParams()`, `getPage()`, …), plus `getToken()` and `getPortApiBaseUrl()` (same data as `PLUGIN_DATA` plus the token). Call **`applyThemeCss()`** to inject the host theme stylesheet (see [Theming and CSS variables](#theming-and-css-variables)).
41
+
42
+ ## Usage
43
+
44
+ ### React
45
+
46
+ Install **`react` ≥ 18**, then import from **`@port-labs/plugins-sdk/react`**:
47
+
48
+ ```bash
49
+ npm install react
50
+ ```
51
+
52
+ ```tsx
53
+ import { usePortPluginData } from '@port-labs/plugins-sdk/react';
54
+
55
+ function MyPlugin() {
56
+ const { portToken, portApiBaseUrl, page, user, entity, params } = usePortPluginData();
57
+
58
+ if (!portToken) return <p>Waiting for host…</p>;
59
+
60
+ return (
61
+ <pre>{JSON.stringify({ page, user, entity, params }, null, 2)}</pre>
62
+ );
63
+ }
64
+ ```
65
+
66
+ To match the Port UI colors, opt in to host theme CSS with **`applyThemeCss`** from the same hook (see [Theming and CSS variables](#theming-and-css-variables)).
67
+
68
+ ### Other frameworks (store + getters)
69
+
70
+ The same host data is available without React. Call **`initPortPluginMessaging()`** once early if you want (getters and `subscribe` call it automatically). Use **`subscribe(listener)`** to re-run when the host sends new data; read state with **`getSnapshot()`**. **`getServerSnapshot()`** is for SSR (empty static snapshot).
71
+
72
+ ```ts
73
+ import {
74
+ getSnapshot,
75
+ getToken,
76
+ subscribe,
77
+ type PluginHostState,
78
+ } from '@port-labs/plugins-sdk';
79
+
80
+ function bindHostToView(update: (state: PluginHostState) => void) {
81
+ const unsub = subscribe(() => update(getSnapshot()));
82
+ update(getSnapshot());
83
+ return unsub;
84
+ }
85
+ ```
86
+
87
+ Synchronous reads anywhere (no extra listeners):
88
+
89
+ ```ts
90
+ import { getToken, getPortApiBaseUrl } from '@port-labs/plugins-sdk';
91
+
92
+ async function callPortSearch(body: unknown) {
93
+ const token = getToken();
94
+ const base = getPortApiBaseUrl();
95
+ if (!token || !base) throw new Error('Plugin not ready');
96
+ // …
97
+ }
98
+ ```
99
+
100
+ ### Merging page filters with a widget search query
101
+
102
+ Use `mergePageFilters` so results respect both the widget query and the dashboard page filters (`page.pageFilters`). Types such as `EntitiesQuery`, `PageQuery`, and `Blueprint` are exported from this package for typing your query and blueprint objects.
103
+
104
+ ```ts
105
+ import { getPage, mergePageFilters, type Blueprint, type EntitiesQuery } from '@port-labs/plugins-sdk';
106
+
107
+ const widgetQuery: EntitiesQuery = {
108
+ combinator: 'and',
109
+ rules: [/* your rules */],
110
+ };
111
+
112
+ const merged = mergePageFilters(widgetQuery, getPage()?.pageFilters, blueprint as Blueprint);
113
+ ```
114
+
115
+ `mergeWidgetQueryWithPageQuery` is an alias for `mergePageFilters`. The constant `DASHBOARD_FILTERS_META_BLUEPRINT` identifies dashboard-wide filter rules in page filter arrays.
116
+
117
+ ## Theming and CSS variables
118
+
119
+ The host can send a **`theme`** object on **`PLUGIN_DATA`**:
120
+
121
+ ```ts
122
+ type Theme = {
123
+ mode: string;
124
+ css: string; // `:root { --background-primary: ...; --text-high: ...; }`
125
+ };
126
+ ```
127
+
128
+ The SDK stores this on **`theme`** in the snapshot and from **`usePortPluginData()`**. To opt in to applying the host theme CSS, call **`applyThemeCss()`** (from the main package or via the hook):
129
+
130
+ ```tsx
131
+ import { useEffect } from 'react';
132
+ import { usePortPluginData } from '@port-labs/plugins-sdk/react';
133
+
134
+ function MyPlugin() {
135
+ const { applyThemeCss } = usePortPluginData();
136
+
137
+ useEffect(() => {
138
+ applyThemeCss();
139
+ }, [applyThemeCss]); // `applyThemeCss` identity updates when host `theme.css` changes
140
+
141
+ // …
142
+ }
143
+ ```
144
+
145
+ Vanilla / non-React:
146
+
147
+ ```ts
148
+ import { applyThemeCss, subscribe } from '@port-labs/plugins-sdk';
149
+
150
+ subscribe(() => {
151
+ applyThemeCss();
152
+ });
153
+ applyThemeCss();
154
+ ```
155
+
156
+ This injects a `<style id="port-plugin-theme">` tag with the theme’s `css` into `document.head`. If the host omits theme or `css`, that element is removed.
157
+
158
+ In your own CSS, consume variables with safe fallbacks, for example:
159
+
160
+ ```css
161
+ body {
162
+ background: rgb(var(--primary, 245, 247, 250));
163
+ color: var(--text-high, #1a1a2e);
164
+ }
165
+
166
+ .plugin-container {
167
+ background: var(--background-primary, #fff);
168
+ }
169
+
170
+ .data-row {
171
+ background: var(--background-contrast, #fff);
172
+ border-color: var(--border-contrast-medium, #e2e8f0);
173
+ }
174
+ ```
175
+
176
+ Common variables you can reuse include (non-exhaustive):
177
+
178
+ - **`--background-primary`**: main surface/background color
179
+ - **`--background-dim`** / **`--background-dim-transparent`**: softer backgrounds and cards
180
+ - **`--background-contrast`**: high-contrast surface
181
+ - **`--text-high`** / **`--text-medium`** / **`--text-low`**: primary, secondary, and subtle text
182
+ - **`--border-medium`** / **`--border-contrast-medium`**: border colors
183
+ - **`--primary`**: RGB triple for the primary color, used via `rgb(var(--primary))`
184
+
185
+ ## API overview
186
+
187
+ ### React entry (`@port-labs/plugins-sdk/react`)
188
+
189
+ | Export | Description |
190
+ | ------ | ----------- |
191
+ | `usePortPluginData` | Hook backed by `useSyncExternalStore` over the same store as the main entry. Includes `theme` and `applyThemeCss` (identity updates when `theme.css` changes so `useEffect(..., [applyThemeCss])` reapplies styles). |
192
+ | Types | Re-exported for convenience: `Theme`, `PluginHostState`, `Page`, `User`, `Entity`, `Params` (same as the main entry). |
193
+
194
+ ### Main entry (`@port-labs/plugins-sdk`)
195
+
196
+ | Export | Description |
197
+ | ------ | ----------- |
198
+ | `getToken`, `getUser`, `getEntity`, `getPage`, `getParams`, `getPortApiBaseUrl`, `getTheme` | Read the current snapshot. |
199
+ | `applyThemeCss` | Apply or clear host theme CSS in `document.head` (`#port-plugin-theme`). |
200
+ | `initPortPluginMessaging` | Ensures the listener is registered (also run automatically by getters and `subscribe`). |
201
+ | `subscribe`, `getSnapshot`, `getServerSnapshot` | Framework-agnostic reactive core (`subscribe` notifies; `getSnapshot` reads). |
202
+ | `mergePageFilters` | AND-merge widget `EntitiesQuery` with page filters and blueprint rules. |
203
+ | `mergeWidgetQueryWithPageQuery` | Alias for `mergePageFilters`. |
204
+ | Types | Host context: `Page`, `User`, `Entity`, `Params`, `Theme`, `PluginHostState`. Search/blueprint: `EntitiesQuery`, `PageQuery`, `Blueprint`, `AnyEntitiesQueryRule`, `PluginParamType`, `PluginParamValue`, … |
205
+
206
+ ## License
207
+
208
+ ISC
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Entity search / page-filter types aligned with Port’s entities search API.
3
+ * Kept structural so published `.d.ts` does not depend on private Port packages.
4
+ */
5
+ /** One rule in a query; Port uses many discriminated variants—this shape accepts all of them. */
6
+ export type AnyEntitiesQueryRule = Record<string, unknown>;
7
+ export type EntitiesQuery = {
8
+ combinator: 'and' | 'or';
9
+ rules: (AnyEntitiesQueryRule | EntitiesQuery)[];
10
+ };
11
+ export type PageQuery = {
12
+ combinator: 'and';
13
+ rules: AnyEntitiesQueryRule[];
14
+ blueprint?: string;
15
+ };
16
+ /** Fields read by `mergePageFilters`; a full Port blueprint satisfies this type. */
17
+ export type Blueprint = {
18
+ identifier: string;
19
+ ownership?: unknown;
20
+ };
21
+ //# sourceMappingURL=entitySearchTypes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entitySearchTypes.d.ts","sourceRoot":"","sources":["../src/entitySearchTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,iGAAiG;AACjG,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE3D,MAAM,MAAM,aAAa,GAAG;IAC3B,UAAU,EAAE,KAAK,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,CAAC,oBAAoB,GAAG,aAAa,CAAC,EAAE,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACvB,UAAU,EAAE,KAAK,CAAC;IAClB,KAAK,EAAE,oBAAoB,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,oFAAoF;AACpF,MAAM,MAAM,SAAS,GAAG;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Entity search / page-filter types aligned with Port’s entities search API.
3
+ * Kept structural so published `.d.ts` does not depend on private Port packages.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=entitySearchTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entitySearchTypes.js","sourceRoot":"","sources":["../src/entitySearchTypes.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * `PLUGIN_DATA.entity` shape aligned with Port’s entity API (changelog fields included).
3
+ */
4
+ export type EntityRelations = Record<string, string | string[] | null>;
5
+ export type EntityScorecard = {
6
+ rules: {
7
+ identifier: string;
8
+ status: 'SUCCESS' | 'FAILURE';
9
+ level: string;
10
+ ruleResults: Array<{
11
+ result: boolean;
12
+ condition?: unknown;
13
+ }>;
14
+ }[];
15
+ level: string;
16
+ };
17
+ export type Entity = {
18
+ _id?: string;
19
+ identifier: string;
20
+ title?: string;
21
+ team?: string[];
22
+ icon?: string;
23
+ blueprint: string;
24
+ properties: Record<string, unknown>;
25
+ relations?: EntityRelations;
26
+ scorecards?: Record<string, EntityScorecard>;
27
+ createdBy: string;
28
+ updatedBy: string;
29
+ createdAt: Date;
30
+ updatedAt: Date;
31
+ };
32
+ //# sourceMappingURL=hostEntity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostEntity.d.ts","sourceRoot":"","sources":["../src/hostEntity.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;AAEvE,MAAM,MAAM,eAAe,GAAG;IAC7B,KAAK,EAAE;QACN,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,SAAS,GAAG,SAAS,CAAC;QAC9B,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,KAAK,CAAC;YAClB,MAAM,EAAE,OAAO,CAAC;YAChB,SAAS,CAAC,EAAE,OAAO,CAAC;SACpB,CAAC,CAAC;KACH,EAAE,CAAC;IACJ,KAAK,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CAChB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * `PLUGIN_DATA.entity` shape aligned with Port’s entity API (changelog fields included).
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=hostEntity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostEntity.js","sourceRoot":"","sources":["../src/hostEntity.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,7 @@
1
+ export type { PluginData, PluginHostPage, PluginHostTheme, PluginUser } from '@port-labs/common-types';
2
+ export type { PluginParamType, PluginParamValue } from '@port-labs/common-types';
3
+ export type { AnyEntitiesQueryRule, Blueprint, EntitiesQuery, PageQuery } from '@port-labs/common-types/apis/port-api';
4
+ export type { Entity, Page, Params, PluginHostState, Theme, User } from './types.js';
5
+ export { DASHBOARD_FILTERS_META_BLUEPRINT, mergePageFilters, mergeWidgetQueryWithPageQuery } from './mergePageFilters.js';
6
+ export { applyThemeCss, getEntity, getPage, getParams, getPortApiBaseUrl, getServerSnapshot, getSnapshot, getTheme, getToken, getUser, initPortPluginMessaging, subscribe, } from './pluginHostMessaging.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACvG,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACjF,YAAY,EAAE,oBAAoB,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AACvH,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,gCAAgC,EAAE,gBAAgB,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;AAC1H,OAAO,EACN,aAAa,EACb,SAAS,EACT,OAAO,EACP,SAAS,EACT,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,uBAAuB,EACvB,SAAS,GACT,MAAM,0BAA0B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { DASHBOARD_FILTERS_META_BLUEPRINT, mergePageFilters, mergeWidgetQueryWithPageQuery } from './mergePageFilters.js';
2
+ export { applyThemeCss, getEntity, getPage, getParams, getPortApiBaseUrl, getServerSnapshot, getSnapshot, getTheme, getToken, getUser, initPortPluginMessaging, subscribe, } from './pluginHostMessaging.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gCAAgC,EAAE,gBAAgB,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;AAC1H,OAAO,EACN,aAAa,EACb,SAAS,EACT,OAAO,EACP,SAAS,EACT,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,uBAAuB,EACvB,SAAS,GACT,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Merges widget entity-search queries with Port page filters passed from the host.
3
+ * Types match `@port-labs/common-types/apis/port-api` (same contract as the Port frontend helper).
4
+ */
5
+ import type { Blueprint, EntitiesQuery, PageQuery } from '@port-labs/common-types/apis/port-api';
6
+ export declare const DASHBOARD_FILTERS_META_BLUEPRINT = "dashboard-filters-meta-blueprint";
7
+ /**
8
+ * Combines `widgetQuery` (the widget’s search body for POST /v1/entities/search) with the
9
+ * page filters applied on the Port page that hosts the plugin. Those filters usually come from
10
+ * `PLUGIN_DATA.page.pageFilters` as `pageQuery`. The result AND-combines the widget query with
11
+ * the relevant page rules so results respect both the widget and the page context. Page rules
12
+ * are narrowed by blueprint (and dashboard-wide filters); if the blueprint has no `ownership`
13
+ * field, `$team` rules from the page are dropped.
14
+ */
15
+ export declare function mergePageFilters(widgetQuery: EntitiesQuery, pageQuery?: PageQuery[], blueprint?: Blueprint): EntitiesQuery;
16
+ export declare const mergeWidgetQueryWithPageQuery: typeof mergePageFilters;
17
+ //# sourceMappingURL=mergePageFilters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mergePageFilters.d.ts","sourceRoot":"","sources":["../src/mergePageFilters.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AAEjG,eAAO,MAAM,gCAAgC,qCAAqC,CAAC;AAEnF;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,CAAC,EAAE,SAAS,GAAG,aAAa,CAyB1H;AAED,eAAO,MAAM,6BAA6B,yBAAmB,CAAC"}
@@ -0,0 +1,32 @@
1
+ export const DASHBOARD_FILTERS_META_BLUEPRINT = 'dashboard-filters-meta-blueprint';
2
+ /**
3
+ * Combines `widgetQuery` (the widget’s search body for POST /v1/entities/search) with the
4
+ * page filters applied on the Port page that hosts the plugin. Those filters usually come from
5
+ * `PLUGIN_DATA.page.pageFilters` as `pageQuery`. The result AND-combines the widget query with
6
+ * the relevant page rules so results respect both the widget and the page context. Page rules
7
+ * are narrowed by blueprint (and dashboard-wide filters); if the blueprint has no `ownership`
8
+ * field, `$team` rules from the page are dropped.
9
+ */
10
+ export function mergePageFilters(widgetQuery, pageQuery, blueprint) {
11
+ if (!pageQuery || pageQuery.length === 0)
12
+ return widgetQuery;
13
+ const relevantPageQueriesRules = pageQuery
14
+ .filter((query) => query.blueprint === blueprint?.identifier ||
15
+ query.blueprint === DASHBOARD_FILTERS_META_BLUEPRINT ||
16
+ query.blueprint === undefined)
17
+ .flatMap((query) => query.rules);
18
+ if (relevantPageQueriesRules.length === 0)
19
+ return widgetQuery;
20
+ if (!blueprint || !('ownership' in blueprint)) {
21
+ return {
22
+ combinator: 'and',
23
+ rules: [widgetQuery, ...relevantPageQueriesRules.filter((rule) => !('property' in rule && rule.property === '$team'))],
24
+ };
25
+ }
26
+ return {
27
+ combinator: 'and',
28
+ rules: [widgetQuery, ...relevantPageQueriesRules],
29
+ };
30
+ }
31
+ export const mergeWidgetQueryWithPageQuery = mergePageFilters;
32
+ //# sourceMappingURL=mergePageFilters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mergePageFilters.js","sourceRoot":"","sources":["../src/mergePageFilters.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,gCAAgC,GAAG,kCAAkC,CAAC;AAEnF;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAA0B,EAAE,SAAuB,EAAE,SAAqB;IAC1G,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,WAAW,CAAC;IAE7D,MAAM,wBAAwB,GAAG,SAAS;SACxC,MAAM,CACN,CAAC,KAAK,EAAE,EAAE,CACT,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,UAAU;QACzC,KAAK,CAAC,SAAS,KAAK,gCAAgC;QACpD,KAAK,CAAC,SAAS,KAAK,SAAS,CAC9B;SACA,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAElC,IAAI,wBAAwB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,WAAW,CAAC;IAE9D,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,WAAW,IAAI,SAAS,CAAC,EAAE,CAAC;QAC/C,OAAO;YACN,UAAU,EAAE,KAAK;YACjB,KAAK,EAAE,CAAC,WAAW,EAAE,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,IAAI,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC;SAC9F,CAAC;IAC3B,CAAC;IAED,OAAO;QACN,UAAU,EAAE,KAAK;QACjB,KAAK,EAAE,CAAC,WAAW,EAAE,GAAG,wBAAwB,CAAC;KACzB,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,MAAM,6BAA6B,GAAG,gBAAgB,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { Entity, Page, Params, PluginHostState, Theme, User } from './types.js';
2
+ /**
3
+ * Ensures a single `window` message listener is registered and requests a token from the host
4
+ * when embedded in an iframe (once per page load). Safe to call multiple times; helps when the
5
+ * host mounts the plugin twice (e.g. React Strict Mode) without missing the token.
6
+ */
7
+ export declare function initPortPluginMessaging(): void;
8
+ export declare function subscribe(listener: () => void): () => void;
9
+ export declare function getSnapshot(): PluginHostState;
10
+ export declare function getServerSnapshot(): PluginHostState;
11
+ export declare function getToken(): string | null;
12
+ export declare function getUser(): User | undefined;
13
+ export declare function getEntity(): Entity | undefined;
14
+ export declare function getPage(): Page | undefined;
15
+ export declare function getParams(): Params;
16
+ export declare function getPortApiBaseUrl(): string | null;
17
+ export declare function getTheme(): Theme | undefined;
18
+ /**
19
+ * Injects or updates a `<style id="port-plugin-theme">` in `document.head` using the latest
20
+ * `theme.css` from the host. Removes that element when there is no theme or no `css`. No-op on
21
+ * the server.
22
+ */
23
+ export declare function applyThemeCss(): void;
24
+ //# sourceMappingURL=pluginHostMessaging.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginHostMessaging.d.ts","sourceRoot":"","sources":["../src/pluginHostMessaging.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AA2DrF;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAW9C;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAM1D;AAED,wBAAgB,WAAW,IAAI,eAAe,CAG7C;AAID,wBAAgB,iBAAiB,IAAI,eAAe,CAEnD;AAED,wBAAgB,QAAQ,IAAI,MAAM,GAAG,IAAI,CAGxC;AAED,wBAAgB,OAAO,IAAI,IAAI,GAAG,SAAS,CAG1C;AAED,wBAAgB,SAAS,IAAI,MAAM,GAAG,SAAS,CAG9C;AAED,wBAAgB,OAAO,IAAI,IAAI,GAAG,SAAS,CAG1C;AAED,wBAAgB,SAAS,IAAI,MAAM,CAGlC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAGjD;AAED,wBAAgB,QAAQ,IAAI,KAAK,GAAG,SAAS,CAG5C;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAiBpC"}
@@ -0,0 +1,132 @@
1
+ const THEME_STYLE_ELEMENT_ID = 'port-plugin-theme';
2
+ const initialState = {
3
+ params: {},
4
+ page: undefined,
5
+ user: undefined,
6
+ entity: undefined,
7
+ theme: undefined,
8
+ token: null,
9
+ portApiBaseUrl: null,
10
+ };
11
+ function parseTheme(value) {
12
+ if (value === null || typeof value !== 'object') {
13
+ return undefined;
14
+ }
15
+ const record = value;
16
+ if (typeof record.mode !== 'string' || typeof record.css !== 'string') {
17
+ return undefined;
18
+ }
19
+ return { mode: record.mode, css: record.css };
20
+ }
21
+ let state = initialState;
22
+ const listeners = new Set();
23
+ let listening = false;
24
+ let requestedPortToken = false;
25
+ function notify() {
26
+ for (const listener of listeners) {
27
+ listener();
28
+ }
29
+ }
30
+ function setState(partial) {
31
+ state = { ...state, ...partial };
32
+ notify();
33
+ }
34
+ function onMessage(event) {
35
+ if (event.data?.type === 'PORT_TOKEN') {
36
+ setState({ token: event.data.token ?? null });
37
+ return;
38
+ }
39
+ if (event.data?.type === 'PLUGIN_DATA') {
40
+ setState({
41
+ params: (event.data.params ?? {}),
42
+ page: (event.data.page ?? {}),
43
+ user: (event.data.user ?? undefined),
44
+ entity: (event.data.entity ?? undefined),
45
+ theme: parseTheme(event.data.theme),
46
+ portApiBaseUrl: event.data.baseUrl ?? null,
47
+ });
48
+ }
49
+ }
50
+ /**
51
+ * Ensures a single `window` message listener is registered and requests a token from the host
52
+ * when embedded in an iframe (once per page load). Safe to call multiple times; helps when the
53
+ * host mounts the plugin twice (e.g. React Strict Mode) without missing the token.
54
+ */
55
+ export function initPortPluginMessaging() {
56
+ if (typeof window === 'undefined' || listening) {
57
+ return;
58
+ }
59
+ listening = true;
60
+ window.addEventListener('message', onMessage);
61
+ if (window.parent !== window && !requestedPortToken) {
62
+ requestedPortToken = true;
63
+ window.parent.postMessage({ type: 'REQUEST_PORT_TOKEN' }, '*');
64
+ }
65
+ }
66
+ export function subscribe(listener) {
67
+ initPortPluginMessaging();
68
+ listeners.add(listener);
69
+ return () => {
70
+ listeners.delete(listener);
71
+ };
72
+ }
73
+ export function getSnapshot() {
74
+ initPortPluginMessaging();
75
+ return state;
76
+ }
77
+ const serverSnapshot = { ...initialState };
78
+ export function getServerSnapshot() {
79
+ return serverSnapshot;
80
+ }
81
+ export function getToken() {
82
+ initPortPluginMessaging();
83
+ return state.token;
84
+ }
85
+ export function getUser() {
86
+ initPortPluginMessaging();
87
+ return state.user;
88
+ }
89
+ export function getEntity() {
90
+ initPortPluginMessaging();
91
+ return state.entity;
92
+ }
93
+ export function getPage() {
94
+ initPortPluginMessaging();
95
+ return state.page;
96
+ }
97
+ export function getParams() {
98
+ initPortPluginMessaging();
99
+ return state.params;
100
+ }
101
+ export function getPortApiBaseUrl() {
102
+ initPortPluginMessaging();
103
+ return state.portApiBaseUrl;
104
+ }
105
+ export function getTheme() {
106
+ initPortPluginMessaging();
107
+ return state.theme;
108
+ }
109
+ /**
110
+ * Injects or updates a `<style id="port-plugin-theme">` in `document.head` using the latest
111
+ * `theme.css` from the host. Removes that element when there is no theme or no `css`. No-op on
112
+ * the server.
113
+ */
114
+ export function applyThemeCss() {
115
+ initPortPluginMessaging();
116
+ if (typeof document === 'undefined') {
117
+ return;
118
+ }
119
+ const css = state.theme?.css;
120
+ const existing = document.getElementById(THEME_STYLE_ELEMENT_ID);
121
+ if (!css) {
122
+ existing?.remove();
123
+ return;
124
+ }
125
+ const styleEl = existing ?? document.createElement('style');
126
+ styleEl.id = THEME_STYLE_ELEMENT_ID;
127
+ styleEl.textContent = css;
128
+ if (!existing) {
129
+ document.head.appendChild(styleEl);
130
+ }
131
+ }
132
+ //# sourceMappingURL=pluginHostMessaging.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginHostMessaging.js","sourceRoot":"","sources":["../src/pluginHostMessaging.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Plugin widget parameter typing (same contract as Port’s `PLUGIN_DATA.params`).
3
+ * Literal union matches `@port-labs/common-consts` `PLUGIN_PARAM_TYPES`.
4
+ */
5
+ export type PluginParamType = 'string' | 'number' | 'boolean' | 'array' | 'object' | 'blueprint';
6
+ export type PluginParamValue = string | number | boolean | unknown[] | Record<string, unknown>;
7
+ /** Values on `PLUGIN_DATA.params`. */
8
+ export type Params = Record<string, {
9
+ type: PluginParamType;
10
+ value: PluginParamValue | undefined;
11
+ }>;
12
+ //# sourceMappingURL=pluginParams.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginParams.d.ts","sourceRoot":"","sources":["../src/pluginParams.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEjG,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/F,sCAAsC;AACtC,MAAM,MAAM,MAAM,GAAG,MAAM,CAC1B,MAAM,EACN;IACC,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,gBAAgB,GAAG,SAAS,CAAC;CACpC,CACD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pluginParams.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginParams.js","sourceRoot":"","sources":["../src/pluginParams.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Subscribes to host `postMessage` data (token, PLUGIN_DATA). Uses one shared listener for the
3
+ * whole app; safe to call from multiple components.
4
+ */
5
+ export declare function usePortPluginData(): {
6
+ params: import("@port-labs/common-types").ExtendedCustomWidgetParamValues;
7
+ page: import("@port-labs/common-types").PluginHostPage | undefined;
8
+ user: import("@port-labs/common-types").PluginUser | undefined;
9
+ entity: import("@port-labs/common-types/apis/port-api").Entity | undefined;
10
+ theme: import("@port-labs/common-types").PluginHostTheme | undefined;
11
+ portToken: string | null;
12
+ portApiBaseUrl: string | null;
13
+ applyThemeCss: () => void;
14
+ };
15
+ //# sourceMappingURL=usePortPluginData.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePortPluginData.d.ts","sourceRoot":"","sources":["../../src/react/usePortPluginData.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,iBAAiB;;;;;;;;;EAgBhC"}
@@ -0,0 +1,24 @@
1
+ import { useCallback, useSyncExternalStore } from 'react';
2
+ import { applyThemeCss, getServerSnapshot, getSnapshot, subscribe } from '../pluginHostMessaging.js';
3
+ /**
4
+ * Subscribes to host `postMessage` data (token, PLUGIN_DATA). Uses one shared listener for the
5
+ * whole app; safe to call from multiple components.
6
+ */
7
+ export function usePortPluginData() {
8
+ const snapshot = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
9
+ const themeCss = snapshot.theme?.css;
10
+ const applyHostThemeCss = useCallback(() => {
11
+ applyThemeCss();
12
+ }, [themeCss]);
13
+ return {
14
+ params: snapshot.params,
15
+ page: snapshot.page,
16
+ user: snapshot.user,
17
+ entity: snapshot.entity,
18
+ theme: snapshot.theme,
19
+ portToken: snapshot.token,
20
+ portApiBaseUrl: snapshot.portApiBaseUrl,
21
+ applyThemeCss: applyHostThemeCss,
22
+ };
23
+ }
24
+ //# sourceMappingURL=usePortPluginData.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePortPluginData.js","sourceRoot":"","sources":["../../src/react/usePortPluginData.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAErG;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAChC,MAAM,QAAQ,GAAG,oBAAoB,CAAC,SAAS,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC;IACjF,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC;IACrC,MAAM,iBAAiB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC1C,aAAa,EAAE,CAAC;IACjB,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IACf,OAAO;QACN,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,SAAS,EAAE,QAAQ,CAAC,KAAK;QACzB,cAAc,EAAE,QAAQ,CAAC,cAAc;QACvC,aAAa,EAAE,iBAAiB;KAChC,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * React integration for `@port-labs/plugins-sdk`.
3
+ * Requires `react` ≥ 18 as a peer dependency when you import this entry.
4
+ */
5
+ export type { Entity, Page, Params, PluginHostState, Theme, User } from './types.js';
6
+ export { usePortPluginData } from './react/usePortPluginData.js';
7
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC"}
package/dist/react.js ADDED
@@ -0,0 +1,2 @@
1
+ export { usePortPluginData } from './react/usePortPluginData.js';
2
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Host bridge types: canonical definitions live in `@port-labs/common-types` (`src/plugin.ts`).
3
+ * This module re-exports them under the shorter names used by the SDK API.
4
+ */
5
+ export type { Entity } from '@port-labs/common-types/apis/port-api';
6
+ export type { PluginHostState, PluginHostPage as Page, PluginHostTheme as Theme, PluginUser as User, } from '@port-labs/common-types';
7
+ export type { ExtendedCustomWidgetParamValues as Params } from '@port-labs/common-types';
8
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,YAAY,EAAE,MAAM,EAAE,MAAM,uCAAuC,CAAC;AACpE,YAAY,EACX,eAAe,EACf,cAAc,IAAI,IAAI,EACtB,eAAe,IAAI,KAAK,EACxB,UAAU,IAAI,IAAI,GAClB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,+BAA+B,IAAI,MAAM,EAAE,MAAM,yBAAyB,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@port-labs/plugins-sdk",
3
+ "packageManager": "yarn@4.12.0",
4
+ "version": "0.0.1",
5
+ "description": "Framework-agnostic SDK for Port embedded plugins (postMessage host bridge, page filter merge); optional React helpers under /react",
6
+ "license": "ISC",
7
+ "type": "module",
8
+ "main": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "./react": {
16
+ "types": "./dist/react.d.ts",
17
+ "default": "./dist/react.js"
18
+ },
19
+ "./package.json": "./package.json"
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsc --build tsconfig.json",
26
+ "lint": "oxlint --type-aware --quiet ./src",
27
+ "lint:fix": "oxlint --type-aware --fix ./src",
28
+ "format": "prettier . --check --ignore-path ../../.prettierignore",
29
+ "format:fix": "prettier . --write --log-level=warn --ignore-path ../../.prettierignore",
30
+ "test": "echo \"No tests yet\" && exit 0"
31
+ },
32
+ "peerDependencies": {
33
+ "react": ">=18.0.0"
34
+ },
35
+ "peerDependenciesMeta": {
36
+ "react": {
37
+ "optional": true
38
+ }
39
+ },
40
+ "devDependencies": {
41
+ "@port-labs/common-types": "workspace:*",
42
+ "@types/react": "^19.0.0",
43
+ "oxlint": "catalog:lint",
44
+ "prettier": "^3.4.2",
45
+ "react": "^19.0.0",
46
+ "typescript": "^5.8.0"
47
+ },
48
+ "engines": {
49
+ "node": ">=22.0.0"
50
+ },
51
+ "publishConfig": {
52
+ "access": "public"
53
+ }
54
+ }