@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 +208 -0
- package/dist/entitySearchTypes.d.ts +21 -0
- package/dist/entitySearchTypes.d.ts.map +1 -0
- package/dist/entitySearchTypes.js +6 -0
- package/dist/entitySearchTypes.js.map +1 -0
- package/dist/hostEntity.d.ts +32 -0
- package/dist/hostEntity.d.ts.map +1 -0
- package/dist/hostEntity.js +5 -0
- package/dist/hostEntity.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/mergePageFilters.d.ts +17 -0
- package/dist/mergePageFilters.d.ts.map +1 -0
- package/dist/mergePageFilters.js +32 -0
- package/dist/mergePageFilters.js.map +1 -0
- package/dist/pluginHostMessaging.d.ts +24 -0
- package/dist/pluginHostMessaging.d.ts.map +1 -0
- package/dist/pluginHostMessaging.js +132 -0
- package/dist/pluginHostMessaging.js.map +1 -0
- package/dist/pluginParams.d.ts +12 -0
- package/dist/pluginParams.d.ts.map +1 -0
- package/dist/pluginParams.js +2 -0
- package/dist/pluginParams.js.map +1 -0
- package/dist/react/usePortPluginData.d.ts +15 -0
- package/dist/react/usePortPluginData.d.ts.map +1 -0
- package/dist/react/usePortPluginData.js +24 -0
- package/dist/react/usePortPluginData.js.map +1 -0
- package/dist/react.d.ts +7 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +2 -0
- package/dist/react.js.map +1 -0
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +54 -0
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 @@
|
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"hostEntity.js","sourceRoot":"","sources":["../src/hostEntity.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/dist/index.d.ts
ADDED
|
@@ -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 @@
|
|
|
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"}
|
package/dist/react.d.ts
ADDED
|
@@ -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 @@
|
|
|
1
|
+
{"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -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 @@
|
|
|
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
|
+
}
|