@t4h.framework/vite-panel-plugin 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +65 -46
- package/dist/client/assets/{index-C8OZoaNO.js → index-UWKX56j_.js} +7 -7
- package/dist/client/index.html +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/node.d.ts +4 -10
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +3 -4
- package/dist/node.js.map +1 -1
- package/dist/panel-api.d.ts +11 -15
- package/dist/panel-api.d.ts.map +1 -1
- package/dist/panel-config.d.ts +8 -24
- package/dist/panel-config.d.ts.map +1 -1
- package/dist/panel-config.js +0 -52
- package/dist/panel-config.js.map +1 -1
- package/dist/vite-panel-plugin.d.ts +3 -3
- package/dist/vite-panel-plugin.d.ts.map +1 -1
- package/dist/vite-panel-plugin.js +2 -2
- package/dist/vite-panel-plugin.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @t4h.framework/vite-panel-plugin
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#151](https://github.com/tech4humans-brasil/framework/pull/151) [`d44eb5e`](https://github.com/tech4humans-brasil/framework/commit/d44eb5e1797f523612c9e2f560b0bb583ab8688f) Thanks [@gusteycamargo](https://github.com/gusteycamargo)! - host owns panel config and run rejection lives in output
|
|
8
|
+
|
|
3
9
|
## 0.1.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -7,14 +7,17 @@ them, input, output, duration, logs, the activity that failed), and an inbox of
|
|
|
7
7
|
activities waiting for an external advance.
|
|
8
8
|
|
|
9
9
|
It ships with `@t4h.framework/dev`, which plugs it into the Vite instance it
|
|
10
|
-
runs in middleware mode
|
|
11
|
-
`framework dev` and open the
|
|
12
|
-
`/_dev/*`) keep going to the dev
|
|
10
|
+
runs in middleware mode and writes the configuration of its own server, so
|
|
11
|
+
there is nothing to install or configure: run `framework dev` and open the
|
|
12
|
+
printed base URL. API paths (`/projects/*`, `/_dev/*`) keep going to the dev
|
|
13
|
+
server; everything else is the panel.
|
|
13
14
|
|
|
14
15
|
## Hosting the panel elsewhere
|
|
15
16
|
|
|
16
17
|
The package is a Vite plugin (`apply: 'serve'`) that serves the pre-built SPA
|
|
17
|
-
from `dist/client` and injects the host configuration in the page
|
|
18
|
+
from `dist/client` and injects the host configuration in the page. The panel
|
|
19
|
+
has no defaults: the host writes the whole configuration, and what it leaves
|
|
20
|
+
out it does not have.
|
|
18
21
|
|
|
19
22
|
```ts
|
|
20
23
|
import panel from '@t4h.framework/vite-panel-plugin'
|
|
@@ -27,7 +30,7 @@ panel({
|
|
|
27
30
|
project: 'billing',
|
|
28
31
|
metadata: { tenant: 'acme', version: 'v3' },
|
|
29
32
|
fields: {
|
|
30
|
-
run: 'input,output,
|
|
33
|
+
run: 'input,output,activities(pendingStatus,childrenCount)',
|
|
31
34
|
runActivity: 'pendingStatus,childrenCount,input,output,pendings,children',
|
|
32
35
|
},
|
|
33
36
|
capabilities: {
|
|
@@ -50,20 +53,20 @@ panel({
|
|
|
50
53
|
})
|
|
51
54
|
```
|
|
52
55
|
|
|
53
|
-
| Option |
|
|
54
|
-
| ---------------------- |
|
|
55
|
-
| `title` | `Framework Panel`
|
|
56
|
-
| `basePath` | `''` (root)
|
|
57
|
-
| `apiUrl` | `/_dev`
|
|
58
|
-
| `project` | the manifest id
|
|
59
|
-
| `metadata` | `{}`
|
|
60
|
-
| `fields` | `{}`
|
|
61
|
-
| `api` |
|
|
62
|
-
| `capabilities.trigger` | `true`
|
|
63
|
-
| `capabilities.advance` | `true`
|
|
64
|
-
| `capabilities.events` | `true`
|
|
65
|
-
| `capabilities.rebuild` | `true`
|
|
66
|
-
| `routes` | `POST /projects/:project/workflows/:workflow/runs` and `PATCH .../runs/:run/activities/:activity`
|
|
56
|
+
| Option | Local dev server (`@t4h.framework/dev`) | Meaning |
|
|
57
|
+
| ---------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
58
|
+
| `title` | `Framework Panel` | Name shown in the sidebar and the browser tab |
|
|
59
|
+
| `basePath` | `''` (root) | Path the panel is mounted at; the plugin only answers under it and injects `<base href>` so the relative asset URLs resolve |
|
|
60
|
+
| `apiUrl` | `/_dev` | Where the panel API described below lives, exactly as the panel should call it: a same-origin path or an absolute URL, with the route paths appended |
|
|
61
|
+
| `project` | absent; the manifest id fills in | Project (app) id, the one id the core defines; shown in the top bar and filled into `:project` of the mirror routes. The only optional value |
|
|
62
|
+
| `metadata` | `{}` | `{ [key]: string }` labels of the host about this panel (the runtime sends `tenant` and `version`); each one is a box in the top bar and fills the `:key` of the same name in the routes |
|
|
63
|
+
| `fields` | `{}` | The `q` the panel sends on `api.runs` (`runs`), `api.run` (`run`) and `api.runActivity` (`runActivity`), in the host's own field-selection grammar; omitted, no `q` is sent |
|
|
64
|
+
| `api` | `/manifest`, `/state`, `/runs`, `/runs/:run`, `/runs/:run/activities/:activity`, … | Where each read and write of the panel API lives under `apiUrl`, as path templates with `:workflow`, `:run` and `:activity`. `state`, `runWorkflow`, `advanceActivity` and `events` are only called behind their capability, so a host without it leaves them out |
|
|
65
|
+
| `capabilities.trigger` | `true` | The host exposes `POST {apiUrl}{api.runWorkflow}` without authorization; otherwise the Run button becomes "Copy as curl" of the mirror route |
|
|
66
|
+
| `capabilities.advance` | `true` | Same for `POST {apiUrl}{api.advanceActivity}` and the inbox |
|
|
67
|
+
| `capabilities.events` | `true` | The host streams `GET {apiUrl}{api.events}`; otherwise the panel never polls and the top bar gets a Refresh button with the time of the last answer |
|
|
68
|
+
| `capabilities.rebuild` | `true` | The host rebuilds the app and starts over, like the dev server: the top bar shows the build state and empty lists mention the last build; off for a host that keeps its runs |
|
|
69
|
+
| `routes` | `POST /projects/:project/workflows/:workflow/runs` and `PATCH .../runs/:run/activities/:activity` | `{ method, path, headers? }` of the authorized routes a client must call, shown as `curl` examples with those headers; `path` is expanded with `project` and `metadata` |
|
|
67
70
|
|
|
68
71
|
The configuration is read from `window.__T4H_PANEL__`, written by the plugin in
|
|
69
72
|
place of the `<!--panel-config-->` marker of `index.html`; `<!--panel-base-->`
|
|
@@ -80,7 +83,6 @@ import {
|
|
|
80
83
|
createPanelAssetsHandler,
|
|
81
84
|
createPanelHandler,
|
|
82
85
|
render,
|
|
83
|
-
resolvePanelConfig,
|
|
84
86
|
} from '@t4h.framework/vite-panel-plugin/node'
|
|
85
87
|
```
|
|
86
88
|
|
|
@@ -88,8 +90,7 @@ import {
|
|
|
88
90
|
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
89
91
|
| `createPanelHandler` | The whole panel as one `node:http` middleware — the page for a navigation under `basePath`, the assets for everything else. What the plugin uses |
|
|
90
92
|
| `createPanelAssetsHandler` | The hashed assets, cached forever, for a host that mounts them at a shared public path; `index: false` so a miss falls through |
|
|
91
|
-
| `render` | `index.html` with the
|
|
92
|
-
| `resolvePanelConfig` | Fills the local defaults into a partial config, what `render` expects; `createPanelHandler` does it for you |
|
|
93
|
+
| `render` | `index.html` with the whole `PanelConfig` and the `<base href>` in place; `{ baseHref }` overrides the default `` `${basePath}/` `` |
|
|
93
94
|
| `PANEL_CLIENT_DIST` | `dist/client`, the built SPA |
|
|
94
95
|
| `PANEL_CLIENT_ASSETS_DIR` | `dist/client/assets`, safe to serve publicly and cache forever — the names are hashed and `index.html` is not in there |
|
|
95
96
|
| `assertPanelBuilt` | Throws when the package was not built |
|
|
@@ -103,13 +104,28 @@ app.use('/panel/assets', createPanelAssetsHandler())
|
|
|
103
104
|
|
|
104
105
|
// inside the authenticated controller of `.../versions/:version/panel`
|
|
105
106
|
return render(
|
|
106
|
-
|
|
107
|
+
{
|
|
108
|
+
title: 'Framework Panel',
|
|
107
109
|
basePath: `/tenants/${tenant}/projects/${project}/versions/${version}/panel`,
|
|
108
|
-
apiUrl: `/tenants/${tenant}/projects/${project}/versions/${version}
|
|
110
|
+
apiUrl: `/tenants/${tenant}/projects/${project}/versions/${version}`,
|
|
109
111
|
project,
|
|
110
112
|
metadata: { tenant, version },
|
|
111
|
-
|
|
112
|
-
|
|
113
|
+
fields: { run: 'input,output' },
|
|
114
|
+
api: {
|
|
115
|
+
manifest: '/manifest.json',
|
|
116
|
+
runs: '/runs',
|
|
117
|
+
run: '/runs/:run' /* … */,
|
|
118
|
+
},
|
|
119
|
+
capabilities: {
|
|
120
|
+
trigger: false,
|
|
121
|
+
advance: false,
|
|
122
|
+
events: false,
|
|
123
|
+
rebuild: false,
|
|
124
|
+
},
|
|
125
|
+
routes: {
|
|
126
|
+
/* the authorized routes, shown as curl */
|
|
127
|
+
},
|
|
128
|
+
},
|
|
113
129
|
{ baseHref: '/panel/' },
|
|
114
130
|
)
|
|
115
131
|
```
|
|
@@ -129,34 +145,37 @@ matched alongside, so the panel never holds more than one page. Child runs are
|
|
|
129
145
|
the exception: "show more" under an activity fetches the next page of 15 and
|
|
130
146
|
keeps the ones already on screen.
|
|
131
147
|
|
|
132
|
-
| Method | Route
|
|
133
|
-
| ------ |
|
|
134
|
-
| `GET` | `/manifest`
|
|
135
|
-
| `GET` | `/state`
|
|
136
|
-
| `GET` | `/runs?status&workflow&id&
|
|
137
|
-
| `GET` | `/runs/:id?q`
|
|
138
|
-
| `GET` | `/runs/:id/activities?limit&offset&q`
|
|
139
|
-
| `GET` | `/runs/:id/activities/:activityId?q`
|
|
140
|
-
| `GET` | `/runs/:id/activities/:activityId/pendings?limit&offset&q`
|
|
141
|
-
| `GET` | `/runs/:id/logs?limit&offset`
|
|
142
|
-
| `GET` | `/activities/waiting?limit&offset`
|
|
143
|
-
| `GET` | `/events`
|
|
144
|
-
| `POST` | `/workflows/:workflowId/runs`
|
|
145
|
-
| `POST` | `/activities/:activityId/advance`
|
|
146
|
-
|
|
147
|
-
`Run` is `{ id, workflow, status,
|
|
148
|
-
|
|
149
|
-
`running | fulfilled | rejected`.
|
|
148
|
+
| Method | Route | Answer |
|
|
149
|
+
| ------ | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
150
|
+
| `GET` | `/manifest` | `{ id, description, workflows: [{ id, description, schema, authorization? }], authorization? }`; a host may leave `authorization` out |
|
|
151
|
+
| `GET` | `/state` | `{ state: 'idle' \| 'starting' \| 'ready' \| 'exited' }`; only called with `capabilities.rebuild` |
|
|
152
|
+
| `GET` | `/runs?status&workflow&id&parentRun&parentActivity&rootOnly&createdAfter&createdBefore&limit&offset` | `{ count, runs: Run[] }` newest first; `id` is a prefix, `createdAfter`/`createdBefore` are ISO 8601 |
|
|
153
|
+
| `GET` | `/runs/:id?q` | `Run & { input, output }`; `q` is `fields.run` |
|
|
154
|
+
| `GET` | `/runs/:id/activities?limit&offset&q` | `{ count, activities: Activity[] }` newest first; `q` is `fields.runActivities` |
|
|
155
|
+
| `GET` | `/runs/:id/activities/:activityId?q` | `Activity & { input, output }`; `q` is `fields.runActivity` |
|
|
156
|
+
| `GET` | `/runs/:id/activities/:activityId/pendings?limit&offset&q` | `{ count, pendings: Pending[] }` newest first; `q` is `fields.runActivityPendings` |
|
|
157
|
+
| `GET` | `/runs/:id/logs?limit&offset` | `{ count, logs: [{ level, args, at }] }` newest first |
|
|
158
|
+
| `GET` | `/activities/waiting?limit&offset` | `{ count, activities: [{ id, pending, run, workflowId, type, schema, timeoutAt }] }` newest first |
|
|
159
|
+
| `GET` | `/events` | SSE: `manifest`, `build:status`, `build:fail`, `app:exit`, `run:created`, `run:updated` (both with a `Run`), `ping`; only opened with `capabilities.events` |
|
|
160
|
+
| `POST` | `/workflows/:workflowId/runs` | Only with `capabilities.trigger`; body is the input, answers `201 { id }` |
|
|
161
|
+
| `POST` | `/activities/:activityId/advance` | Only with `capabilities.advance`; body `{ payload }`, answers `{ id, type, status }` |
|
|
162
|
+
|
|
163
|
+
`Run` is `{ id, workflow, status, parentWorkflowRun,
|
|
164
|
+
parentWorkflowRunActivity, createdAt, updatedAt }` with `status` in
|
|
165
|
+
`running | fulfilled | rejected`. A rejected run or activity carries its
|
|
166
|
+
reason as `output`: an error-shaped one (`{ message, stack? }`) is shown as
|
|
167
|
+
text, anything else as JSON, and the activity that failed is the one with
|
|
168
|
+
`status: 'rejected'`. `Activity` is `{ id, type, kind, createdAt }`
|
|
150
169
|
plus, on request, `hasChildren`, `input` and `output`; an async one (`kind:
|
|
151
170
|
'async'`) also carries `completedAt` and, on request, `pendingStatus` (status
|
|
152
|
-
of its last pending). `Pending` is `{ id,
|
|
171
|
+
of its last pending). `Pending` is `{ id, previous, status, schema, timeoutAt,
|
|
153
172
|
result, payload, createdAt, updatedAt }`.
|
|
154
173
|
|
|
155
174
|
No answer embeds a list: a run does not carry its activities, an activity does
|
|
156
175
|
not carry its pendings or the runs it started. Each is its own paged route,
|
|
157
176
|
newest first, and the trace reads one page at a time when the reader gets
|
|
158
177
|
there: the activities of the run, the pendings of an open async activity, and
|
|
159
|
-
the runs an activity started as `GET /runs?
|
|
178
|
+
the runs an activity started as `GET /runs?parentActivity=…`, 15 at a time
|
|
160
179
|
behind "show more", since a `startWorkflowMany` can fan out to hundreds of
|
|
161
180
|
thousands. A sync activity records no completion: the trace
|
|
162
181
|
takes the next activity starting, or the run ending, as its end. Every listing
|