@octonodes/ui-extensions 0.1.7 → 0.2.11
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 +105 -0
- package/dist/app/index.d.ts +5 -0
- package/dist/app/index.d.ts.map +1 -0
- package/dist/app/index.js +51 -0
- package/dist/app/index.js.map +1 -0
- package/dist/app/project.d.ts +11 -0
- package/dist/app/project.d.ts.map +1 -0
- package/dist/app/project.js +56 -0
- package/dist/app/project.js.map +1 -0
- package/dist/app/server.d.ts +9 -0
- package/dist/app/server.d.ts.map +1 -0
- package/dist/app/server.js +33 -0
- package/dist/app/server.js.map +1 -0
- package/dist/app/types.d.ts +70 -0
- package/dist/app/types.d.ts.map +1 -0
- package/dist/app/types.js +2 -0
- package/dist/app/types.js.map +1 -0
- package/dist/index.d.ts +27 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -1
- package/dist/index.js.map +1 -1
- package/dist/react.d.ts +19 -0
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +48 -1
- package/dist/react.js.map +1 -1
- package/package.json +14 -6
package/README.md
CHANGED
|
@@ -40,3 +40,108 @@ ui: {
|
|
|
40
40
|
`octonodes plugin build` bundles the entry into the immutable plugin artifact. Octonode loads it only for the exact installed plugin version and renders real host-owned form controls inside an isolated, network-disabled sandbox.
|
|
41
41
|
|
|
42
42
|
The first public target is `node.inspector.inputs`. Undeclared or omitted inputs fall back to the standard inspector form.
|
|
43
|
+
|
|
44
|
+
## Extension-only apps
|
|
45
|
+
|
|
46
|
+
Apps can contribute only a workspace block; a page and backend are optional. Use the same
|
|
47
|
+
`defineExtension` / `startExtension` SDK with `workspace.block` or `app.page` and bundle as a
|
|
48
|
+
browser IIFE. Select **Extension only** in Partner and upload the JavaScript. Octonode stores
|
|
49
|
+
immutable bytes and checks the digest at publication and launch. The static sandbox has no
|
|
50
|
+
direct network access; the scoped host bridge below provides approved project actions.
|
|
51
|
+
|
|
52
|
+
Declare shared string settings in the v2 manifest and read them through
|
|
53
|
+
`getAppSession().configuration`. Customers configure or disable the app under its installation
|
|
54
|
+
settings. Blocks appear in workspace home; an `app.page` or self-hosted web app
|
|
55
|
+
can have an Open app link.
|
|
56
|
+
See `examples/workspace-notice-app` and `docs/plugins.md` in the engine repository.
|
|
57
|
+
|
|
58
|
+
## Self-hosted apps
|
|
59
|
+
|
|
60
|
+
This is also the SDK selected for Octonode's developer-authored app extensions. The engine owns its source in `packages/ui-extensions`; `scripts/sync-plugin-sdk.mjs` synchronizes the public package into `octonode-devtools`. Do not create a second app UI SDK.
|
|
61
|
+
|
|
62
|
+
App targets are `app.page` and `workspace.block`. Register an app in Partner → Apps, publish its HTTPS application URL and extension bundle digests, then install it from Studio → App marketplace. Plugin marketplace remains dedicated to executable node plugins.
|
|
63
|
+
|
|
64
|
+
App controls use the same host design system: `NodeForm`, `Section`, `Button`, and `TextField`. `InputField` is only for node inspectors. Bundle your entry as a browser IIFE, including React and this SDK, and call `startExtension`:
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
import { useState } from "react";
|
|
68
|
+
import { getAppSession } from "@octonodes/ui-extensions";
|
|
69
|
+
import { defineExtension, startExtension, NodeForm, Section, Button, TextField } from "@octonodes/ui-extensions/react";
|
|
70
|
+
|
|
71
|
+
function App() {
|
|
72
|
+
const [note, setNote] = useState("");
|
|
73
|
+
const [status, setStatus] = useState("");
|
|
74
|
+
async function save() {
|
|
75
|
+
try {
|
|
76
|
+
const session = getAppSession();
|
|
77
|
+
const response = await fetch("https://your-app.example/notes", {
|
|
78
|
+
method: "POST",
|
|
79
|
+
headers: { authorization: `Bearer ${session.token}`, "content-type": "application/json" },
|
|
80
|
+
body: JSON.stringify({ note }),
|
|
81
|
+
});
|
|
82
|
+
if (!response.ok) throw new Error("Save failed");
|
|
83
|
+
setStatus("Saved");
|
|
84
|
+
} catch {
|
|
85
|
+
setStatus("Could not save. Reopen the app and try again.");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return (
|
|
89
|
+
<NodeForm>
|
|
90
|
+
<Section title="Project notes">
|
|
91
|
+
<TextField label="Note" value={note} onChange={setNote} />
|
|
92
|
+
<Button onPress={() => void save()}>Save note</Button>
|
|
93
|
+
{status}
|
|
94
|
+
</Section>
|
|
95
|
+
</NodeForm>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
startExtension(defineExtension("app.page", App));
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Host the compiled JavaScript with CORS enabled for the Studio origin. Hash the exact response bytes with SHA-256 and publish the prefixed digest (`sha256:…`). Redirects and bundles larger than 2 MiB are rejected. The hidden iframe has an opaque origin: your backend must accept CORS `Origin: null` for authenticated SDK requests; never use Origin as authorization. Its CSP allows connections only to the registered application origin. Octonode credentials and parent DOM access are unavailable.
|
|
102
|
+
|
|
103
|
+
The five-minute `octo_app_` bearer is specific to the app installation, approved version, and opening user. Your backend must verify it on **every request** with `GET https://octonodes.com/api/apps/runtime/session`, then check that the returned `appId` equals your registered app ID. Use the verified workspace/user identity rather than values supplied by the browser. Never log the bearer or cache verification. Uninstall, consent changes, session expiry, and removed membership revoke subsequent access.
|
|
104
|
+
|
|
105
|
+
For standalone pages, Octonode opens the registered application URL with `#octonode_session=…`. Read the fragment and immediately remove it using `history.replaceState`; keep the credential in memory. App backends can use `POST /api/apps/runtime/data` for consented project/table/row operations, and `POST /api/apps/runtime/executions` on the cloud gateway for workflow execution. Neither credential works as a general Octonode login. See the engine’s `docs/plugins.md` for request examples.
|
|
106
|
+
|
|
107
|
+
For legacy self-hosted v1 apps, developers host app backends and versioned extension assets themselves. Octonode-managed app hosting is reserved for a future paid service. App release metadata pins extension URLs and SHA-256 digests; publishing metadata does not deploy a backend.
|
|
108
|
+
|
|
109
|
+
## Project and workflow access
|
|
110
|
+
|
|
111
|
+
Installed `app.page` and `workspace.block` extensions can use the host bridge without a developer backend. It verifies the live installation, actor, and project grant on every action. A project-specific host can supply its current project; workspace-wide surfaces select a project automatically only when exactly one project is granted.
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
import { connectApp } from "@octonodes/ui-extensions/app";
|
|
115
|
+
|
|
116
|
+
const app = await connectApp();
|
|
117
|
+
const project = app.project ?? app.forProject(chosenProjectId);
|
|
118
|
+
const products = await project.tables.rows.list("products");
|
|
119
|
+
const run = await project.wf.run("sync-products", { source: "app" });
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`app.projects` lists the granted project IDs for a project picker. `app.project` is undefined when no project is granted or several are granted without a current project. `forProject(id)` rejects ungranted IDs locally; Octonode still checks current grants on every request. `wf.run` queues a workflow and returns its execution summary. Pass an `idempotencyKey` option when retrying the same action.
|
|
123
|
+
|
|
124
|
+
A developer-hosted backend can use the same project API after verifying the browser's app bearer. Configure the API URL and your own registered app ID on the server; never accept either from an incoming request.
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
import { connectAppServer } from "@octonodes/ui-extensions/app/server";
|
|
128
|
+
|
|
129
|
+
const app = await connectAppServer(bearer, {
|
|
130
|
+
appId: process.env.OCTONODE_APP_ID!,
|
|
131
|
+
baseUrl: process.env.OCTONODE_API_URL!,
|
|
132
|
+
});
|
|
133
|
+
const project = app.project ?? app.forProject(chosenProjectId);
|
|
134
|
+
const products = await project.tables.rows.list("products");
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The backend helper verifies the bearer on each `connectAppServer` call and uses that bearer only for the app runtime endpoints. Sessions expire after five minutes; background work requires a separately approved installation service identity.
|
|
138
|
+
|
|
139
|
+
## End-to-end app guides
|
|
140
|
+
|
|
141
|
+
The public Playbook is the source for the complete authoring path:
|
|
142
|
+
[quickstart](https://playbook.octonodes.com/docs/apps-quickstart),
|
|
143
|
+
[project configuration](https://playbook.octonodes.com/docs/apps-configuration),
|
|
144
|
+
[SDK imports and permissions](https://playbook.octonodes.com/docs/apps-sdk),
|
|
145
|
+
[hosting](https://playbook.octonodes.com/docs/apps-hosting), and
|
|
146
|
+
[publishing and updates](https://playbook.octonodes.com/docs/apps-publishing).
|
|
147
|
+
The CLI scaffold supplies a runnable extension-only or full app example.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { AppContext } from "./types.js";
|
|
2
|
+
export type { AppBridgeRequest, AppBridgeResponse, AppContext, AppExecution, AppGrant, AppProject } from "./types.js";
|
|
3
|
+
/** Connects an installed extension to its live workspace and project grants. */
|
|
4
|
+
export declare function connectApp(): Promise<AppContext>;
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/app/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAuC,UAAU,EAAY,MAAM,YAAY,CAAC;AAE5F,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA8CtH,gFAAgF;AAChF,wBAAsB,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,CAUtD"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Generated from packages/ui-extensions/src/app/index.ts. Do not edit; run the Octonode SDK sync.
|
|
2
|
+
import { getAppSession, UI_EXTENSION_API_VERSION } from "../index.js";
|
|
3
|
+
import { appContext } from "./project.js";
|
|
4
|
+
function request(operation, body) {
|
|
5
|
+
getAppSession();
|
|
6
|
+
if (parent === window)
|
|
7
|
+
throw new Error("App actions require an installed extension");
|
|
8
|
+
const requestId = crypto.randomUUID();
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
const timeout = setTimeout(() => finish(new Error("App action timed out")), 30_000);
|
|
11
|
+
const retry = operation === "context" ? setInterval(send, 1_000) : undefined;
|
|
12
|
+
const receive = (event) => {
|
|
13
|
+
const message = event.data;
|
|
14
|
+
if (event.source !== parent ||
|
|
15
|
+
message?.octonode !== "ui-extension" ||
|
|
16
|
+
message.type !== "app-response" ||
|
|
17
|
+
message.apiVersion !== UI_EXTENSION_API_VERSION ||
|
|
18
|
+
message.requestId !== requestId)
|
|
19
|
+
return;
|
|
20
|
+
finish(message.ok ? undefined : new Error(message.error || "App action failed"), message.value);
|
|
21
|
+
};
|
|
22
|
+
function finish(error, value) {
|
|
23
|
+
clearTimeout(timeout);
|
|
24
|
+
clearInterval(retry);
|
|
25
|
+
removeEventListener("message", receive);
|
|
26
|
+
if (error)
|
|
27
|
+
reject(error);
|
|
28
|
+
else
|
|
29
|
+
resolve(value);
|
|
30
|
+
}
|
|
31
|
+
addEventListener("message", receive);
|
|
32
|
+
function send() {
|
|
33
|
+
parent.postMessage({
|
|
34
|
+
octonode: "ui-extension",
|
|
35
|
+
apiVersion: UI_EXTENSION_API_VERSION,
|
|
36
|
+
type: "app-request",
|
|
37
|
+
requestId,
|
|
38
|
+
operation,
|
|
39
|
+
body,
|
|
40
|
+
}, "*");
|
|
41
|
+
}
|
|
42
|
+
send();
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/** Connects an installed extension to its live workspace and project grants. */
|
|
46
|
+
export async function connectApp() {
|
|
47
|
+
const session = getAppSession();
|
|
48
|
+
const verified = await request("context");
|
|
49
|
+
return appContext(session, verified, request);
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/app/index.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAK1C,SAAS,OAAO,CAAI,SAAwC,EAAE,IAAc;IAC1E,aAAa,EAAE,CAAC;IAChB,IAAI,MAAM,KAAK,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IACrF,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IACtC,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACxC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACpF,MAAM,KAAK,GAAG,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7E,MAAM,OAAO,GAAG,CAAC,KAAmB,EAAE,EAAE;YACtC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAyC,CAAC;YAChE,IACE,KAAK,CAAC,MAAM,KAAK,MAAM;gBACvB,OAAO,EAAE,QAAQ,KAAK,cAAc;gBACpC,OAAO,CAAC,IAAI,KAAK,cAAc;gBAC/B,OAAO,CAAC,UAAU,KAAK,wBAAwB;gBAC/C,OAAO,CAAC,SAAS,KAAK,SAAS;gBAE/B,OAAO;YACT,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,IAAI,mBAAmB,CAAC,EAAE,OAAO,CAAC,KAAU,CAAC,CAAC;QACvG,CAAC,CAAC;QACF,SAAS,MAAM,CAAC,KAAa,EAAE,KAAS;YACtC,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,aAAa,CAAC,KAAK,CAAC,CAAC;YACrB,mBAAmB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YACxC,IAAI,KAAK;gBAAE,MAAM,CAAC,KAAK,CAAC,CAAC;;gBACpB,OAAO,CAAC,KAAU,CAAC,CAAC;QAC3B,CAAC;QACD,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACrC,SAAS,IAAI;YACX,MAAM,CAAC,WAAW,CAChB;gBACE,QAAQ,EAAE,cAAc;gBACxB,UAAU,EAAE,wBAAwB;gBACpC,IAAI,EAAE,aAAa;gBACnB,SAAS;gBACT,SAAS;gBACT,IAAI;aACsB,EAC5B,GAAG,CACJ,CAAC;QACJ,CAAC;QACD,IAAI,EAAE,CAAC;IACT,CAAC,CAAC,CAAC;AACL,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAChC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAM3B,SAAS,CAAC,CAAC;IACd,OAAO,UAAU,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AppSession } from "../index.js";
|
|
2
|
+
import type { AppBridgeRequest, AppContext, AppGrant } from "./types.js";
|
|
3
|
+
export type AppRequest = <T>(operation: AppBridgeRequest["operation"], body?: unknown) => Promise<T>;
|
|
4
|
+
export declare function appContext(session: Pick<AppSession, "appId" | "installationId" | "workspace" | "projectId">, verified: {
|
|
5
|
+
appId: string;
|
|
6
|
+
installationId: string;
|
|
7
|
+
userId: string;
|
|
8
|
+
workspace: AppContext["workspace"];
|
|
9
|
+
grants: AppGrant[];
|
|
10
|
+
}, request: AppRequest): AppContext;
|
|
11
|
+
//# sourceMappingURL=project.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/app/project.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAgB,QAAQ,EAAc,MAAM,YAAY,CAAC;AAEnG,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,gBAAgB,CAAC,WAAW,CAAC,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;AAoCrG,wBAAgB,UAAU,CACxB,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,gBAAgB,GAAG,WAAW,GAAG,WAAW,CAAC,EACjF,QAAQ,EAAE;IACR,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IACnC,MAAM,EAAE,QAAQ,EAAE,CAAC;CACpB,EACD,OAAO,EAAE,UAAU,GAClB,UAAU,CAyBZ"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
function project(id, request) {
|
|
2
|
+
return {
|
|
3
|
+
id,
|
|
4
|
+
get: () => request("data", { operation: "project.get", projectId: id }),
|
|
5
|
+
tables: {
|
|
6
|
+
list: () => request("data", { operation: "tables.list", projectId: id }),
|
|
7
|
+
rows: {
|
|
8
|
+
list: (tableId, input = {}) => request("data", { operation: "rows.list", projectId: id, tableId, input }),
|
|
9
|
+
insert: (tableId, data) => request("data", { operation: "rows.insert", projectId: id, tableId, input: { data } }),
|
|
10
|
+
update: (tableId, rowId, data, expectedVersion) => request("data", {
|
|
11
|
+
operation: "rows.update",
|
|
12
|
+
projectId: id,
|
|
13
|
+
tableId,
|
|
14
|
+
rowId,
|
|
15
|
+
input: { data, expectedVersion },
|
|
16
|
+
}),
|
|
17
|
+
delete: (tableId, rowId) => request("data", { operation: "rows.delete", projectId: id, tableId, rowId }),
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
wf: {
|
|
21
|
+
run: (workflowId, input = {}, options = {}) => request("workflow.run", {
|
|
22
|
+
projectId: id,
|
|
23
|
+
workflowId,
|
|
24
|
+
input,
|
|
25
|
+
idempotencyKey: options.idempotencyKey ?? crypto.randomUUID(),
|
|
26
|
+
...(options.env ? { env: options.env } : {}),
|
|
27
|
+
}),
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function appContext(session, verified, request) {
|
|
32
|
+
if (session.appId !== verified.appId ||
|
|
33
|
+
session.installationId !== verified.installationId ||
|
|
34
|
+
session.workspace.kind !== verified.workspace.kind ||
|
|
35
|
+
session.workspace.id !== verified.workspace.id)
|
|
36
|
+
throw new Error("App session identity changed");
|
|
37
|
+
const projects = [...new Set(verified.grants.map((grant) => grant.projectId))];
|
|
38
|
+
if (session.projectId && !projects.includes(session.projectId))
|
|
39
|
+
throw new Error("Current project is not granted to this app");
|
|
40
|
+
const currentProjectId = session.projectId ?? (projects.length === 1 ? projects[0] : undefined);
|
|
41
|
+
return {
|
|
42
|
+
appId: verified.appId,
|
|
43
|
+
installationId: verified.installationId,
|
|
44
|
+
userId: verified.userId,
|
|
45
|
+
workspace: verified.workspace,
|
|
46
|
+
grants: verified.grants,
|
|
47
|
+
projects,
|
|
48
|
+
project: currentProjectId ? project(currentProjectId, request) : undefined,
|
|
49
|
+
forProject(projectId) {
|
|
50
|
+
if (!projects.includes(projectId))
|
|
51
|
+
throw new Error("Project is not granted to this app");
|
|
52
|
+
return project(projectId, request);
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/app/project.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AppContext } from "./types.js";
|
|
2
|
+
export type { AppContext, AppExecution, AppGrant, AppProject } from "./types.js";
|
|
3
|
+
/** Verify the browser's app bearer before using it from a developer-hosted backend. */
|
|
4
|
+
export declare function connectAppServer(token: string, options: {
|
|
5
|
+
appId: string;
|
|
6
|
+
baseUrl: string;
|
|
7
|
+
projectId?: string;
|
|
8
|
+
}): Promise<AppContext>;
|
|
9
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/app/server.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAY,MAAM,YAAY,CAAC;AAEvD,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEjF,uFAAuF;AACvF,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9D,OAAO,CAAC,UAAU,CAAC,CAgCrB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Generated from packages/ui-extensions/src/app/server.ts. Do not edit; run the Octonode SDK sync.
|
|
2
|
+
import { appContext } from "./project.js";
|
|
3
|
+
/** Verify the browser's app bearer before using it from a developer-hosted backend. */
|
|
4
|
+
export async function connectAppServer(token, options) {
|
|
5
|
+
if (!/^octo_app_[A-Za-z0-9_-]{43}$/.test(token))
|
|
6
|
+
throw new Error("Invalid app session");
|
|
7
|
+
const base = new URL(options.baseUrl);
|
|
8
|
+
if (base.protocol !== "https:" && !(base.protocol === "http:" && ["localhost", "127.0.0.1"].includes(base.hostname)))
|
|
9
|
+
throw new Error("Octonode API URL must use HTTPS");
|
|
10
|
+
const request = async (operation, body) => {
|
|
11
|
+
const path = operation === "context"
|
|
12
|
+
? "/api/apps/runtime/session"
|
|
13
|
+
: operation === "data"
|
|
14
|
+
? "/api/apps/runtime/data"
|
|
15
|
+
: "/api/apps/runtime/executions";
|
|
16
|
+
const response = await fetch(new URL(path, base), {
|
|
17
|
+
method: operation === "context" ? "GET" : "POST",
|
|
18
|
+
headers: {
|
|
19
|
+
authorization: `Bearer ${token}`,
|
|
20
|
+
...(operation === "context" ? {} : { "content-type": "application/json" }),
|
|
21
|
+
},
|
|
22
|
+
...(operation === "context" ? {} : { body: JSON.stringify(body) }),
|
|
23
|
+
});
|
|
24
|
+
if (!response.ok)
|
|
25
|
+
throw new Error(`Octonode app request failed (${response.status})`);
|
|
26
|
+
return response.json();
|
|
27
|
+
};
|
|
28
|
+
const verified = await request("context");
|
|
29
|
+
if (verified.appId !== options.appId)
|
|
30
|
+
throw new Error("App session belongs to another app");
|
|
31
|
+
return appContext({ ...verified, projectId: options.projectId }, verified, request);
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/app/server.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,OAAO,EAAE,UAAU,EAAmB,MAAM,cAAc,CAAC;AAK3D,uFAAuF;AACvF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAa,EACb,OAA+D;IAE/D,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACxF,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,KAAK,OAAO,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClH,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,MAAM,OAAO,GAAe,KAAK,EAAK,SAA8C,EAAE,IAAc,EAAc,EAAE;QAClH,MAAM,IAAI,GACR,SAAS,KAAK,SAAS;YACrB,CAAC,CAAC,2BAA2B;YAC7B,CAAC,CAAC,SAAS,KAAK,MAAM;gBACpB,CAAC,CAAC,wBAAwB;gBAC1B,CAAC,CAAC,8BAA8B,CAAC;QACvC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE;YAChD,MAAM,EAAE,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM;YAChD,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,KAAK,EAAE;gBAChC,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;aAC3E;YACD,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;SACnE,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;QACtF,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAC;IACvC,CAAC,CAAC;IACF,MAAM,QAAQ,GAAG,MAAM,OAAO,CAM3B,SAAS,CAAC,CAAC;IACd,IAAI,QAAQ,CAAC,KAAK,KAAK,OAAO,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAC5F,OAAO,UAAU,CAAC,EAAE,GAAG,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AACtF,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { AppSession } from "../index.js";
|
|
2
|
+
export type AppGrant = {
|
|
3
|
+
action: "projects:read" | "data:read" | "data:write" | "workflows:run";
|
|
4
|
+
projectId: string;
|
|
5
|
+
};
|
|
6
|
+
export type AppExecution = {
|
|
7
|
+
requestHash: string;
|
|
8
|
+
dispatchPending: boolean;
|
|
9
|
+
runId: string;
|
|
10
|
+
workflowId: string;
|
|
11
|
+
status: "queued" | "running" | "succeeded" | "failed" | "cancelled" | "interrupted";
|
|
12
|
+
submittedAt: number;
|
|
13
|
+
startedAt?: number;
|
|
14
|
+
finishedAt?: number;
|
|
15
|
+
result?: unknown;
|
|
16
|
+
error?: string;
|
|
17
|
+
};
|
|
18
|
+
export type AppProject = {
|
|
19
|
+
id: string;
|
|
20
|
+
get(): Promise<{
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
}>;
|
|
24
|
+
tables: {
|
|
25
|
+
list(): Promise<unknown>;
|
|
26
|
+
rows: {
|
|
27
|
+
list(tableId: string, input?: {
|
|
28
|
+
cursor?: string;
|
|
29
|
+
limit?: number;
|
|
30
|
+
}): Promise<unknown>;
|
|
31
|
+
insert(tableId: string, data: Record<string, unknown>): Promise<unknown>;
|
|
32
|
+
update(tableId: string, rowId: string, data: Record<string, unknown>, expectedVersion: number): Promise<unknown>;
|
|
33
|
+
delete(tableId: string, rowId: string): Promise<unknown>;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
wf: {
|
|
37
|
+
run(workflowId: string, input?: Record<string, unknown>, options?: {
|
|
38
|
+
idempotencyKey?: string;
|
|
39
|
+
env?: string;
|
|
40
|
+
}): Promise<AppExecution>;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
export type AppContext = {
|
|
44
|
+
appId: AppSession["appId"];
|
|
45
|
+
installationId: AppSession["installationId"];
|
|
46
|
+
userId: string;
|
|
47
|
+
workspace: AppSession["workspace"];
|
|
48
|
+
grants: readonly AppGrant[];
|
|
49
|
+
projects: readonly string[];
|
|
50
|
+
project: AppProject | undefined;
|
|
51
|
+
forProject(projectId: string): AppProject;
|
|
52
|
+
};
|
|
53
|
+
export type AppBridgeRequest = {
|
|
54
|
+
octonode: "ui-extension";
|
|
55
|
+
apiVersion: "1";
|
|
56
|
+
type: "app-request";
|
|
57
|
+
requestId: string;
|
|
58
|
+
operation: "context" | "data" | "workflow.run";
|
|
59
|
+
body?: unknown;
|
|
60
|
+
};
|
|
61
|
+
export type AppBridgeResponse = {
|
|
62
|
+
octonode: "ui-extension";
|
|
63
|
+
apiVersion: "1";
|
|
64
|
+
type: "app-response";
|
|
65
|
+
requestId: string;
|
|
66
|
+
ok: boolean;
|
|
67
|
+
value?: unknown;
|
|
68
|
+
error?: string;
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/app/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/app/types.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
export declare const UI_EXTENSION_API_VERSION: "1";
|
|
2
|
-
export declare const UI_EXTENSION_TARGETS: readonly ["node.inspector.inputs"];
|
|
2
|
+
export declare const UI_EXTENSION_TARGETS: readonly ["node.inspector.inputs", "app.page", "workspace.block"];
|
|
3
3
|
export type UiExtensionTarget = (typeof UI_EXTENSION_TARGETS)[number];
|
|
4
4
|
export type UiExtensionTree = {
|
|
5
5
|
type: "text";
|
|
6
6
|
value: string;
|
|
7
|
+
} | {
|
|
8
|
+
type: "button";
|
|
9
|
+
id: string;
|
|
10
|
+
label: string;
|
|
11
|
+
disabled: boolean;
|
|
12
|
+
} | {
|
|
13
|
+
type: "text-field";
|
|
14
|
+
id: string;
|
|
15
|
+
label: string;
|
|
16
|
+
value: string;
|
|
17
|
+
disabled: boolean;
|
|
7
18
|
} | {
|
|
8
19
|
type: "node-form";
|
|
9
20
|
children: UiExtensionTree[];
|
|
@@ -35,4 +46,19 @@ export declare function validateExtensionMessage(value: unknown, expectedTarget:
|
|
|
35
46
|
message: UiExtensionMessage;
|
|
36
47
|
inputNames: string[];
|
|
37
48
|
} | null;
|
|
49
|
+
export interface AppSession {
|
|
50
|
+
configuration: Readonly<Record<string, string>>;
|
|
51
|
+
token: string;
|
|
52
|
+
expiresAt: number;
|
|
53
|
+
appId: string;
|
|
54
|
+
installationId: string;
|
|
55
|
+
workspace: {
|
|
56
|
+
kind: "user" | "team" | "org";
|
|
57
|
+
id: string;
|
|
58
|
+
};
|
|
59
|
+
projectId?: string;
|
|
60
|
+
version: string;
|
|
61
|
+
}
|
|
62
|
+
/** Available only inside an installed app extension. Send this bearer to your own backend for verification. */
|
|
63
|
+
export declare function getAppSession(): AppSession;
|
|
38
64
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,wBAAwB,EAAG,GAAY,CAAC;AACrD,eAAO,MAAM,oBAAoB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,wBAAwB,EAAG,GAAY,CAAC;AACrD,eAAO,MAAM,oBAAoB,mEAAoE,CAAC;AAEtG,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GACnF;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,eAAe,EAAE,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,eAAe,EAAE,CAAA;CAAE,GAC/D;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,aAAa,GAAG,WAAW,CAAA;CAAE,CAAC;AAEpF,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,cAAc,CAAC;IACzB,UAAU,EAAE,OAAO,wBAAwB,CAAC;IAC5C,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,iBAAiB,CAAC;IAC1B,IAAI,EAAE,eAAe,CAAC;CACvB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,cAAc,CAAC;IACzB,UAAU,EAAE,OAAO,wBAAwB,CAAC;IAC5C,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,kBAAkB,GAAG,wBAAwB,GAAG,uBAAuB,CAAC;AAOpF,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,EACd,cAAc,EAAE,iBAAiB,GAChC;IAAE,OAAO,EAAE,kBAAkB,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAwD9D;AAED,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AACD,+GAA+G;AAC/G,wBAAgB,aAAa,IAAI,UAAU,CAI1C"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Generated from packages/ui-extensions/src/index.ts. Do not edit; run the Octonode SDK sync.
|
|
2
2
|
export const UI_EXTENSION_API_VERSION = "1";
|
|
3
|
-
export const UI_EXTENSION_TARGETS = ["node.inspector.inputs"];
|
|
3
|
+
export const UI_EXTENSION_TARGETS = ["node.inspector.inputs", "app.page", "workspace.block"];
|
|
4
4
|
const MAX_NODES = 100;
|
|
5
5
|
const MAX_DEPTH = 10;
|
|
6
6
|
const MAX_TEXT = 4_000;
|
|
@@ -27,7 +27,21 @@ export function validateExtensionMessage(value, expectedTarget) {
|
|
|
27
27
|
const candidate = node;
|
|
28
28
|
if (candidate.type === "text")
|
|
29
29
|
return typeof candidate.value === "string" && candidate.value.length <= MAX_TEXT;
|
|
30
|
+
if (candidate.type === "button" || candidate.type === "text-field") {
|
|
31
|
+
return (expectedTarget !== "node.inspector.inputs" &&
|
|
32
|
+
typeof candidate.id === "string" &&
|
|
33
|
+
candidate.id.length > 0 &&
|
|
34
|
+
candidate.id.length <= 100 &&
|
|
35
|
+
typeof candidate.label === "string" &&
|
|
36
|
+
candidate.label.trim().length > 0 &&
|
|
37
|
+
candidate.label.length <= 240 &&
|
|
38
|
+
typeof candidate.disabled === "boolean" &&
|
|
39
|
+
(candidate.type === "button" ||
|
|
40
|
+
("value" in candidate && typeof candidate.value === "string" && candidate.value.length <= MAX_TEXT)));
|
|
41
|
+
}
|
|
30
42
|
if (candidate.type === "input-field") {
|
|
43
|
+
if (expectedTarget !== "node.inspector.inputs")
|
|
44
|
+
return false;
|
|
31
45
|
if (typeof candidate.name !== "string" ||
|
|
32
46
|
!INPUT_NAME.test(candidate.name) ||
|
|
33
47
|
(candidate.appearance !== undefined &&
|
|
@@ -51,4 +65,11 @@ export function validateExtensionMessage(value, expectedTarget) {
|
|
|
51
65
|
? { message: message, inputNames: [...new Set(inputNames)] }
|
|
52
66
|
: null;
|
|
53
67
|
}
|
|
68
|
+
/** Available only inside an installed app extension. Send this bearer to your own backend for verification. */
|
|
69
|
+
export function getAppSession() {
|
|
70
|
+
const session = globalThis.__octonodeApp;
|
|
71
|
+
if (!session || session.expiresAt <= Date.now())
|
|
72
|
+
throw new Error("App session expired; reopen the app");
|
|
73
|
+
return session;
|
|
74
|
+
}
|
|
54
75
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAY,CAAC;AACrD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,uBAAuB,CAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/react.d.ts
CHANGED
|
@@ -22,5 +22,24 @@ export declare function InputField({ name, appearance }: {
|
|
|
22
22
|
name: string;
|
|
23
23
|
appearance: "single-line" | "multiline" | undefined;
|
|
24
24
|
}, string | import("react").JSXElementConstructor<any>>;
|
|
25
|
+
export declare function Button({ children, onPress, disabled, }: {
|
|
26
|
+
children: string;
|
|
27
|
+
onPress: () => void;
|
|
28
|
+
disabled?: boolean;
|
|
29
|
+
}): import("react").ReactElement<{
|
|
30
|
+
"data-id": string;
|
|
31
|
+
"data-disabled": string;
|
|
32
|
+
}, string | import("react").JSXElementConstructor<any>>;
|
|
33
|
+
export declare function TextField({ label, value, onChange, disabled, }: {
|
|
34
|
+
label: string;
|
|
35
|
+
value: string;
|
|
36
|
+
onChange: (value: string) => void;
|
|
37
|
+
disabled?: boolean;
|
|
38
|
+
}): import("react").ReactElement<{
|
|
39
|
+
"data-id": string;
|
|
40
|
+
label: string;
|
|
41
|
+
value: string;
|
|
42
|
+
"data-disabled": string;
|
|
43
|
+
}, string | import("react").JSXElementConstructor<any>>;
|
|
25
44
|
export declare function startExtension(extension: UiExtensionDefinition): void;
|
|
26
45
|
//# sourceMappingURL=react.d.ts.map
|
package/dist/react.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"AACA,OAAO,EAAmC,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE5F,OAAO,EAAE,wBAAwB,EAAE,KAAK,iBAAiB,EAAwB,MAAM,SAAS,CAAC;AAEjG,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,OAAO,wBAAwB,CAAC;IAC5C,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,EAAE,aAAa,CAAC;CAC1B;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,iBAAiB,EAAE,SAAS,EAAE,aAAa,GAAG,qBAAqB,CAE1G;AAED,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,+EAE9D;AAED,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE;;wDAEnF;AAED,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,aAAa,GAAG,WAAW,CAAA;CAAE;;;wDAE1G;AAGD,wBAAgB,MAAM,CAAC,EACrB,QAAQ,EACR,OAAO,EACP,QAAgB,GACjB,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;;;wDASA;AACD,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,KAAK,EACL,QAAQ,EACR,QAAgB,GACjB,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;;;;;wDASA;AAyCD,wBAAgB,cAAc,CAAC,SAAS,EAAE,qBAAqB,GAAG,IAAI,CAqDrE"}
|
package/dist/react.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Generated from packages/ui-extensions/src/react.tsx. Do not edit; run the Octonode SDK sync.
|
|
2
|
-
import { createElement } from "react";
|
|
2
|
+
import { useId, useEffect, createElement } from "react";
|
|
3
3
|
import { createRoot } from "react-dom/client";
|
|
4
4
|
import { UI_EXTENSION_API_VERSION } from "./index";
|
|
5
5
|
export function defineExtension(target, component) {
|
|
@@ -14,6 +14,27 @@ export function Section({ title, children }) {
|
|
|
14
14
|
export function InputField({ name, appearance }) {
|
|
15
15
|
return createElement("octonode-input-field", { name, appearance });
|
|
16
16
|
}
|
|
17
|
+
const callbacks = new Map();
|
|
18
|
+
export function Button({ children, onPress, disabled = false, }) {
|
|
19
|
+
const id = useId();
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
callbacks.set(id, onPress);
|
|
22
|
+
return () => {
|
|
23
|
+
callbacks.delete(id);
|
|
24
|
+
};
|
|
25
|
+
}, [id, onPress]);
|
|
26
|
+
return createElement("octonode-button", { "data-id": id, "data-disabled": String(disabled) }, children);
|
|
27
|
+
}
|
|
28
|
+
export function TextField({ label, value, onChange, disabled = false, }) {
|
|
29
|
+
const id = useId();
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
callbacks.set(id, (value) => onChange(value ?? ""));
|
|
32
|
+
return () => {
|
|
33
|
+
callbacks.delete(id);
|
|
34
|
+
};
|
|
35
|
+
}, [id, onChange]);
|
|
36
|
+
return createElement("octonode-text-field", { "data-id": id, label, value, "data-disabled": String(disabled) });
|
|
37
|
+
}
|
|
17
38
|
function serialize(node) {
|
|
18
39
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
19
40
|
const value = node.textContent?.trim();
|
|
@@ -25,6 +46,21 @@ function serialize(node) {
|
|
|
25
46
|
const serialized = serialize(child);
|
|
26
47
|
return serialized ? [serialized] : [];
|
|
27
48
|
});
|
|
49
|
+
if (node.localName === "octonode-button")
|
|
50
|
+
return {
|
|
51
|
+
type: "button",
|
|
52
|
+
id: node.getAttribute("data-id") ?? "",
|
|
53
|
+
label: node.textContent ?? "",
|
|
54
|
+
disabled: node.getAttribute("data-disabled") === "true",
|
|
55
|
+
};
|
|
56
|
+
if (node.localName === "octonode-text-field")
|
|
57
|
+
return {
|
|
58
|
+
type: "text-field",
|
|
59
|
+
id: node.getAttribute("data-id") ?? "",
|
|
60
|
+
label: node.getAttribute("label") ?? "",
|
|
61
|
+
value: node.getAttribute("value") ?? "",
|
|
62
|
+
disabled: node.getAttribute("data-disabled") === "true",
|
|
63
|
+
};
|
|
28
64
|
if (node.localName === "octonode-node-form")
|
|
29
65
|
return { type: "node-form", children };
|
|
30
66
|
if (node.localName === "octonode-section")
|
|
@@ -40,6 +76,17 @@ function serialize(node) {
|
|
|
40
76
|
return null;
|
|
41
77
|
}
|
|
42
78
|
export function startExtension(extension) {
|
|
79
|
+
addEventListener("message", (event) => {
|
|
80
|
+
if (event.source !== parent ||
|
|
81
|
+
event.data?.octonode !== "ui-extension" ||
|
|
82
|
+
event.data?.type !== "event" ||
|
|
83
|
+
event.data?.target !== extension.target)
|
|
84
|
+
return;
|
|
85
|
+
const { id, value } = event.data;
|
|
86
|
+
if (typeof id !== "string" || (value !== undefined && (typeof value !== "string" || value.length > 4000)))
|
|
87
|
+
return;
|
|
88
|
+
callbacks.get(id)?.(value);
|
|
89
|
+
});
|
|
43
90
|
const root = document.createElement("div");
|
|
44
91
|
document.body.append(root);
|
|
45
92
|
let queued = false;
|
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,OAAO,EAAE,aAAa,EAAsC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octonodes/ui-extensions",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Portable contracts and React primitives for Octonode plugin UI extensions.",
|
|
7
|
-
"repository": {
|
|
8
|
-
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/nivdoron1/octonode-devtools.git",
|
|
10
|
-
"directory": "packages/ui-extensions"
|
|
11
|
-
},
|
|
12
7
|
"main": "dist/index.js",
|
|
13
8
|
"types": "dist/index.d.ts",
|
|
14
9
|
"exports": {
|
|
@@ -20,6 +15,14 @@
|
|
|
20
15
|
"types": "./dist/react.d.ts",
|
|
21
16
|
"import": "./dist/react.js"
|
|
22
17
|
},
|
|
18
|
+
"./app": {
|
|
19
|
+
"types": "./dist/app/index.d.ts",
|
|
20
|
+
"import": "./dist/app/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./app/server": {
|
|
23
|
+
"types": "./dist/app/server.d.ts",
|
|
24
|
+
"import": "./dist/app/server.js"
|
|
25
|
+
},
|
|
23
26
|
"./testing": {
|
|
24
27
|
"types": "./dist/testing.d.ts",
|
|
25
28
|
"import": "./dist/testing.js"
|
|
@@ -37,5 +40,10 @@
|
|
|
37
40
|
"@types/react-dom": "19.2.4",
|
|
38
41
|
"react": "19.2.8",
|
|
39
42
|
"react-dom": "19.2.8"
|
|
43
|
+
},
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "git+https://github.com/nivdoron1/octonode-devtools.git",
|
|
47
|
+
"directory": "packages/ui-extensions"
|
|
40
48
|
}
|
|
41
49
|
}
|