@metricinsights/pp-dev 1.1.1 → 1.2.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/CHANGELOG.md +30 -0
- package/README.md +42 -1
- package/TEMPLATE_VARIABLES.md +125 -0
- package/dist/CHANGELOG.md +30 -0
- package/dist/README.md +42 -1
- package/dist/cjs/cli.js +1 -1
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/index-XIFH2ace.js +2 -0
- package/dist/cjs/index-XIFH2ace.js.map +1 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/package.json +9 -5
- package/dist/cjs/plugin-lLb1ogcl.js +2 -0
- package/dist/cjs/plugin-lLb1ogcl.js.map +1 -0
- package/dist/cjs/plugin.js +1 -1
- package/dist/cjs/{version-plugin-Bhywa-Hu.js → version-plugin-C0xv4wbw.js} +2 -2
- package/dist/cjs/{version-plugin-Bhywa-Hu.js.map → version-plugin-C0xv4wbw.js.map} +1 -1
- package/dist/client/client.css +1 -1
- package/dist/client/client.css.map +1 -1
- package/dist/client/client.js +128 -2
- package/dist/client/client.js.map +1 -1
- package/dist/client/index.html +1 -0
- package/dist/esm/cli.js +1 -1
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/index-BtZKQ3Ni.js +2 -0
- package/dist/esm/index-BtZKQ3Ni.js.map +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/package.json +9 -5
- package/dist/esm/plugin-BtTlYPNc.js +2 -0
- package/dist/esm/plugin-BtTlYPNc.js.map +1 -0
- package/dist/esm/plugin.js +1 -1
- package/dist/esm/{version-plugin-Lyuzh4c2.js → version-plugin-7_CHPYR-.js} +2 -2
- package/dist/esm/{version-plugin-Lyuzh4c2.js.map → version-plugin-7_CHPYR-.js.map} +1 -1
- package/docs/features.md +99 -0
- package/docs/screenshots/01-panel-expanded.png +0 -0
- package/docs/screenshots/02-panel-minimized.png +0 -0
- package/docs/screenshots/03-panel-settings.png +0 -0
- package/docs/screenshots/04-inspector-list.png +0 -0
- package/docs/screenshots/05-inspector-detail.png +0 -0
- package/docs/screenshots/06-editor-schema.png +0 -0
- package/docs/screenshots/07-editor-schema-advanced.png +0 -0
- package/docs/screenshots/08-editor-schema-help-modal.png +0 -0
- package/docs/screenshots/09-editor-values.png +0 -0
- package/docs/screenshots/10-editor-values-json.png +0 -0
- package/docs/screenshots/11-editor-theme-light.png +0 -0
- package/docs/screenshots/12-editor-theme-dark.png +0 -0
- package/package.json +10 -6
- package/scripts/patch-npm-bundled-vulnerabilities.mjs +66 -11
- package/dist/cjs/index-ctxv-2Kt.js +0 -2
- package/dist/cjs/index-ctxv-2Kt.js.map +0 -1
- package/dist/cjs/plugin-cgWPoZgR.js +0 -2
- package/dist/cjs/plugin-cgWPoZgR.js.map +0 -1
- package/dist/esm/index-N58WZBr_.js +0 -2
- package/dist/esm/index-N58WZBr_.js.map +0 -1
- package/dist/esm/plugin-ClbE2EOy.js +0 -2
- package/dist/esm/plugin-ClbE2EOy.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,33 @@
|
|
|
1
|
+
# [1.2.0-beta.3](https://github.com/mi-examples/pp-dev/compare/v1.2.0-beta.2...v1.2.0-beta.3) (2026-08-07)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* Variables Editor client script fails to parse, blanking the whole UI ([2e48b2e](https://github.com/mi-examples/pp-dev/commit/2e48b2e69c12124a6d300503a80b40f649de1316))
|
|
7
|
+
|
|
8
|
+
# [1.2.0-beta.2](https://github.com/mi-examples/pp-dev/compare/v1.2.0-beta.1...v1.2.0-beta.2) (2026-08-07)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* address CodeRabbit review feedback on PR [#227](https://github.com/mi-examples/pp-dev/issues/227) ([3f64e42](https://github.com/mi-examples/pp-dev/commit/3f64e42a9ffd213160fd14d300e0516099b8683d))
|
|
14
|
+
|
|
15
|
+
# [1.2.0-beta.1](https://github.com/mi-examples/pp-dev/compare/v1.1.1-beta.1...v1.2.0-beta.1) (2026-08-07)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* address npm audit vulnerabilities in root and test fixtures ([a33aad3](https://github.com/mi-examples/pp-dev/commit/a33aad3ca7a24078d6a8293ebe45e065baf62d0b))
|
|
21
|
+
* Variables Editor — ergonomic advanced-fields toggle, confirm before delete ([6cc96ee](https://github.com/mi-examples/pp-dev/commit/6cc96eef13dfeb12684e136e43ade115981a33d4))
|
|
22
|
+
* Variables Editor tab switch no longer blanks out until the fetch resolves ([399930d](https://github.com/mi-examples/pp-dev/commit/399930d4da7e1e846f52648cfeae9509b9c36402))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
* add Auto/Dark/Light theme switcher, shared across the dev panel, Inspector, and Variables Editor ([b6f72a6](https://github.com/mi-examples/pp-dev/commit/b6f72a68181105dd620db967307bd3e3575911fe))
|
|
28
|
+
* add page-variables API and schema/export/validation helpers ([36c727e](https://github.com/mi-examples/pp-dev/commit/36c727e7feeb45805ccae76984aaa755be2e8d7b))
|
|
29
|
+
* add standalone Variables Editor page with dev-panel entry points ([40bc88e](https://github.com/mi-examples/pp-dev/commit/40bc88e45fd9b25d4a6d47249ef791272ff92c20))
|
|
30
|
+
|
|
1
31
|
## [1.1.1-beta.1](https://github.com/mi-examples/pp-dev/compare/v1.1.0...v1.1.1-beta.1) (2026-07-27)
|
|
2
32
|
|
|
3
33
|
|
package/README.md
CHANGED
|
@@ -18,6 +18,8 @@ lives of PP developers easier:
|
|
|
18
18
|
|
|
19
19
|
pp-dev is based on [Vite](https://vitejs.dev/).
|
|
20
20
|
|
|
21
|
+
📸 **[Feature tour](./docs/features.md)** — screenshots of the dev panel, Request Inspector, and Variables Editor.
|
|
22
|
+
|
|
21
23
|
## Installation
|
|
22
24
|
|
|
23
25
|
```bash
|
|
@@ -472,6 +474,8 @@ For custom build configuration, create a `vite.config` file. See [Vite Configura
|
|
|
472
474
|
|
|
473
475
|
pp-dev injects a floating dev panel into every served page. It shows the package name and version, the backend URL, the template mode and the App ID, and hosts the template **Sync** button. Since 1.0 the panel is fully repositionable and can be hidden.
|
|
474
476
|
|
|
477
|
+

|
|
478
|
+
|
|
475
479
|
### Position
|
|
476
480
|
|
|
477
481
|
The panel can be anchored to any of the four screen corners (default: bottom-right). Three ways to move it:
|
|
@@ -486,13 +490,17 @@ The minimize arrow, the panel's shadow, rounded corner and slide direction all m
|
|
|
486
490
|
|
|
487
491
|
Toggle **Auto-hide** in the settings popover (or set `devPanel.autoHide: true`). The panel slides behind the nearest screen edge leaving a 4px accent strip; hovering the strip for ~300 ms slides it out, and it hides again ~500 ms after the pointer leaves. Keyboard focus inside the panel keeps it revealed. While auto-hide is active the minimize arrow acts as a **pin** button that returns the panel to normal mode.
|
|
488
492
|
|
|
493
|
+
### Theme
|
|
494
|
+
|
|
495
|
+
The settings popover has an **Auto / Dark / Light** switcher. "Auto" follows the OS/browser preference; the other two force an override. The choice is shared (via the same `localStorage` key) with the standalone [Request Inspector](#request-inspector) and [Variables Editor](#variables-editor) pages, which also each have their own copy of the switcher for when they're opened directly without the panel present.
|
|
496
|
+
|
|
489
497
|
### Hiding and restoring
|
|
490
498
|
|
|
491
499
|
**Hide panel** in the settings popover (or `devPanel.hidden: true`) removes the panel from view entirely. To bring it back, open any page with `?pp-dev-panel=show` in the URL — the override persists across reloads. The symmetric `?pp-dev-panel=hide` hides it, which is handy for demos and clean screenshots.
|
|
492
500
|
|
|
493
501
|
### State persistence
|
|
494
502
|
|
|
495
|
-
Runtime choices are saved in the browser's `localStorage` (`pp-dev-info-position`, `pp-dev-info-auto-hide`, `pp-dev-info-hidden`) and take precedence over config values. **Reset to config defaults** in the settings popover clears all overrides. Storage is origin-scoped: overrides apply to every pp-dev app served on the same host and port, and a Metric Insights page that clears origin storage will reset them to config defaults.
|
|
503
|
+
Runtime choices are saved in the browser's `localStorage` (`pp-dev-info-position`, `pp-dev-info-auto-hide`, `pp-dev-info-hidden`, `pp-dev-info-theme`) and take precedence over config values. **Reset to config defaults** in the settings popover clears all overrides. Storage is origin-scoped: overrides apply to every pp-dev app served on the same host and port, and a Metric Insights page that clears origin storage will reset them to config defaults.
|
|
496
504
|
|
|
497
505
|
### Configuration
|
|
498
506
|
|
|
@@ -509,6 +517,33 @@ export default defineConfig({
|
|
|
509
517
|
|
|
510
518
|
See the [`devPanel` option reference](#devpanel--dev-panel-appearance) for details.
|
|
511
519
|
|
|
520
|
+
### Page variables
|
|
521
|
+
|
|
522
|
+
For pages with a template (`app.type: 'template'`), the settings popover has:
|
|
523
|
+
|
|
524
|
+
- **Reload variables** — refetches the page's live variable values from MI right now (bypassing the usual request-level cache) and reloads the page, so `[VarName]` substitution reflects a just-saved value without restarting the dev server.
|
|
525
|
+
- **Open variables editor…** — opens the standalone [Variables Editor](#variables-editor) page.
|
|
526
|
+
|
|
527
|
+
Pages without a template (`app.type: 'page'`) have no variables, so this group — and the button that opens the editor — is hidden.
|
|
528
|
+
|
|
529
|
+
### Variables Editor
|
|
530
|
+
|
|
531
|
+
A standalone page at `/@pp-dev/variables-editor`, alongside the [Request Inspector](#request-inspector), with two tabs:
|
|
532
|
+
|
|
533
|
+
- **Schema** — view/edit the template's `__template_variables.json` (add/remove variables, change type, default, `additional_options`, etc.), with a raw-JSON escape hatch.
|
|
534
|
+
|
|
535
|
+

|
|
536
|
+
|
|
537
|
+
- **Values** — edit the page's live variable values in place, with type-aware widgets (searchable select for `static` options, a per-item form for `list`, …). A JSON mode (`View/edit raw JSON`) shows/accepts the same values as plain JSON — list-type values as native arrays, not double-escaped strings — with **Save to JSON file…** / **Import from JSON file…** buttons, and flags values that don't match a declared option, changed since the last load, or aren't in the schema.
|
|
538
|
+
|
|
539
|
+

|
|
540
|
+
|
|
541
|
+
Both the active tab and Values' JSON mode are reflected in the URL (`?tab=values&mode=json`), so a specific view can be bookmarked or shared.
|
|
542
|
+
|
|
543
|
+
See the [feature tour](./docs/features.md#variables-editor) for more screenshots, including the advanced/raw-JSON views and the theme switcher.
|
|
544
|
+
|
|
545
|
+
See [`TEMPLATE_VARIABLES.md`](./TEMPLATE_VARIABLES.md) — also shipped inside the published package — for the `__template_variables.json` schema this feature reads.
|
|
546
|
+
|
|
512
547
|
## Request Inspector
|
|
513
548
|
|
|
514
549
|
pp-dev includes a built-in request inspector that captures every proxied and locally-served HTTP request made during development. It is enabled by default.
|
|
@@ -521,6 +556,12 @@ Open `http://localhost:3000/@pp-dev/inspector` (replace port as needed) in any b
|
|
|
521
556
|
- Full request and response headers, with a **Copy** button per section
|
|
522
557
|
- Request and response bodies rendered as text for JSON/HTML/CSS/plain-text content types, with **Copy** and **Save** buttons
|
|
523
558
|
- Binary bodies (images, fonts, archives) show metadata only and offer a **Save** button
|
|
559
|
+
|
|
560
|
+

|
|
561
|
+
|
|
562
|
+
Selecting a request opens the detail pane with headers and a syntax-highlighted body:
|
|
563
|
+
|
|
564
|
+

|
|
524
565
|
- A **Clear** button in the top-right removes all stored entries
|
|
525
566
|
|
|
526
567
|
### Source badges
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# `__template_variables.json` schema (MI reference)
|
|
2
|
+
|
|
3
|
+
This file is what Metric Insights (MI) writes/reads for a Portal Page **template**'s variables — its definitions (types, defaults, per-field config) live here, while the *live* values a page currently has are stored separately on the page itself (see below). pp-dev's standalone [Variables Editor](./README.md#variables-editor) page (`src/lib/variables-editor.ts`, backed by `src/lib/page-variables-diff.ts`) reads and writes this file's contents; the older backup/sync flow (`src/lib/dist.service.ts`, `TEMPLATE_VARIABLES_FILE_NAME`) only ever tracked it as an opaque blob (hash) for diffing, never parsing it.
|
|
4
|
+
|
|
5
|
+
## File location
|
|
6
|
+
|
|
7
|
+
- Filename: `__template_variables.json`
|
|
8
|
+
- In a Portal Page project, it normally lives at `public/__template_variables.json`.
|
|
9
|
+
- Produced by MI when exporting a template's assets; consumed by MI when template assets are synced back (e.g. via git-sync, or saving the template in MI's own editor).
|
|
10
|
+
|
|
11
|
+
## Top-level shape
|
|
12
|
+
|
|
13
|
+
```jsonc
|
|
14
|
+
{
|
|
15
|
+
"tags": [ /* TemplateVariableTag[] — see below */ ],
|
|
16
|
+
"settings": {
|
|
17
|
+
"image_capture_timeout": 0,
|
|
18
|
+
"image_capture_on_event": "...",
|
|
19
|
+
"image_capture_css_selector": "..."
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`tags` is the variable schema/definitions. `settings` is unrelated template-capture config — not a variable.
|
|
25
|
+
|
|
26
|
+
## `TemplateVariableTag` fields
|
|
27
|
+
|
|
28
|
+
| Field | Type | Notes |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| `name` | `string` | Unique variable name. This is the key that appears in the live page's `tags` (`{name, value}[]`, see below) and in `[VarName]` placeholders substituted by `pp.middleware.ts#buildPage()`. |
|
|
31
|
+
| `uid` | `string` | Stable md5 identifier, survives renames across syncs. |
|
|
32
|
+
| `tag_type` | `enum` | One of: `text`, `select`, `multiselect`, `file`, `list`, `color`, `boolean`. (`boolean` is a newer addition — older templates may not have it.) |
|
|
33
|
+
| `tag_source` | `enum` | One of: `static`, `page`, `element`, `folder`, `segment`, `dataset`, `dataset_data`, `announcement`, `group`, `category`, `custom_attribute`, `page_entity`. Describes where the value/options come from, not the value's shape. |
|
|
34
|
+
| `default_value` | `string` | Default value for the variable. For `tag_type: "list"`, this is a **JSON-encoded array** (string-of-JSON, not a nested array). |
|
|
35
|
+
| `additional_options` | `array \| object \| string` | Decoded JSON in the exported file (re-stringified on ingest). Shape depends on `tag_type` and, for `select`/`multiselect`, on `tag_source` — see the dedicated section below for the full per-source breakdown. Always absent/unused for `boolean`. |
|
|
36
|
+
| `description` | `string` | Markdown, rendered as such in MI's editor UI. |
|
|
37
|
+
| `use_hmtl_editor_ind` | `'Y' \| 'N'` | Whether the value is edited via a rich HTML editor. |
|
|
38
|
+
| `use_raw_html_ind` | `'Y' \| 'N'` | When `'Y'`, MI skips XSS-encoding the value on save (see caveat below). |
|
|
39
|
+
| `use_json_editor_ind` | `'Y' \| 'N'` | Whether the value is edited via a JSON editor. |
|
|
40
|
+
| `javascript_code` | `string \| null` | Optional JS snippet, with `[value]` substituted at render time. |
|
|
41
|
+
| `display_order` | `number` | Present explicitly in real exports (not just implied by array index) — matches the tag's position in `tags`. |
|
|
42
|
+
| `portal_page_template_tag_id` | `number` | MI's internal row id for this tag. Not needed to write a schema by hand — MI regenerates it. |
|
|
43
|
+
| `portal_page_template_id` | `number` | The owning template's id — same for every tag in one file. |
|
|
44
|
+
| `use_js_code_ind` | `'Y' \| 'N'` | Companion flag for `javascript_code` (whether it's active), seen alongside `use_hmtl_editor_ind`/`use_raw_html_ind`/`use_json_editor_ind` in real exports. |
|
|
45
|
+
|
|
46
|
+
There is **no** `label` or `required` field, and no generic `options`/`enum` key — option lists live inside `additional_options`.
|
|
47
|
+
|
|
48
|
+
`javascript_code`/`use_js_code_ind` are real, change-tracked columns, but MI's current "Create/Edit Variable" form has no field for either — there's no live path to set them through that UI today. Treat them as legacy/reserved: safe to read and preserve on a round-trip, but not something to expect a human to fill in via MI's own tooling. pp-dev's Variables Editor matches this and doesn't expose an editor for them either — it still reads/writes them untouched as part of each tag object.
|
|
49
|
+
|
|
50
|
+
A real example covering every `tag_type` — including a dataset-driven `select` with non-enumerable `additional_options`, a flat-string `list`, and a column-defined `list` of objects (`ListItemFieldConfig[]`, see below) — lives at `tests/test-commonjs/public/__template_variables.json` in this repo.
|
|
51
|
+
|
|
52
|
+
## Live page variable values vs. the schema
|
|
53
|
+
|
|
54
|
+
The schema above (`__template_variables.json`) is **separate** from the live values stored on a Portal Page:
|
|
55
|
+
|
|
56
|
+
- Live values: `Page.tags` — a JSON string of `{name, value}[]` — fetched/set via a dedicated endpoint, **not** `/api/page`:
|
|
57
|
+
- `GET /api/page_variable?page_id=<id>` → `{ tags: [{name, value}, ...] }`
|
|
58
|
+
- `PUT /api/page_variable?page_id=<id>` with body `{ tags: "<JSON-stringified {name,value}[]>" }`
|
|
59
|
+
- `page_id` is the preferred identifier for both — pp-dev uses it exclusively (see `src/api/page-variable.ts`, `PageVariableAPI#getById`/`#updateById`). `internal_name` also works as a fallback (`?internal_name=<name>` on either verb) but requires an extra page lookup to resolve first if you only have the numeric page id, so there's no reason to use it here.
|
|
60
|
+
- The route also accepts an `id`-style path/query param (`/api/page_variable/id/{id}`, `?id=...`) for **PUT only** — for **GET**, sending an `id` routes to a handler that's explicitly disabled, so **`id` must never be used for GET** — use `page_id` instead.
|
|
61
|
+
- MI resolves the page for this endpoint via `page_id` first, falling back to `internal_name` only when `page_id` is absent.
|
|
62
|
+
- MI's tag-saving logic does **not** validate a value against the variable's declared `tag_type`. It only special-cases `tag_type === 'list'` (JSON encode/decode the array + XSS-encode each element) vs. everything else (plain XSS-encode as a string), and skips encoding entirely when `use_raw_html_ind === 'Y'` or `use_hmtl_editor_ind === 'Y'`. So `select`, `multiselect`, `boolean`, `color`, and `file` values are all persisted as unvalidated strings by MI itself — there is no server-side type/enum enforcement to lean on.
|
|
63
|
+
|
|
64
|
+
## `list` of objects — `additional_options` as `ListItemFieldConfig[]`
|
|
65
|
+
|
|
66
|
+
A `list` variable isn't limited to flat strings. When `additional_options` is a non-empty array, MI's own page-variable editor treats each entry as a **column definition** and renders each list item as an object keyed by those column names — this is a real, first-class MI feature, not something pp-dev invented.
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
interface ListItemFieldConfig {
|
|
70
|
+
name: string; // becomes the object key on each list item
|
|
71
|
+
type: 'textarea' | 'color' | 'select' | 'multi-select' | 'file';
|
|
72
|
+
source?: string; // select/multi-select only — where THIS field's options come from
|
|
73
|
+
additional_options?: string; // not actually read for select/multi-select — see below
|
|
74
|
+
options?: string[]; // select/multi-select only — the option list itself
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
A bare string in the array is shorthand for `{ name: <that string>, type: 'textarea' }`. With `additional_options` empty (`""`), items fall back to being plain strings. `tests/test-commonjs/public/__template_variables.json` in this repo has both variants side by side: `variable-list` (flat strings) and `variable-list-objects` (column-defined — `additional_options: [{name:"id",type:"textarea"},{name:"label",type:"textarea"}]`, items like `{"id":"1","label":"First"}`).
|
|
79
|
+
|
|
80
|
+
For a `select`/`multi-select` column, `source` (defaults to `'static'` if omitted) and `options` together follow the **exact same per-source rules** as the tag-level `tag_source`/`additional_options` pair described above — just fed by `options` (a plain `string[]`) instead of the tag's own `additional_options`. Concretely: with `source: 'static'` (or omitted), `options` **is** the list of choices; for any other `source`, the same live-loading/ignored-field rules apply, just scoped to this one column instead of the whole tag. MI's own list-item value editor never actually reads this column config's `additional_options` — only `options` — so leave it out rather than mirroring the tag-level shape here.
|
|
81
|
+
|
|
82
|
+
pp-dev validates list items against this schema (`validateListItems` in `src/lib/page-variables-diff.ts`, best-effort/warning-only like everything else here): each item must be an object with every declared field present and no undeclared extra fields, `color` fields must match a hex pattern, and `select`/`multi-select` fields are checked against `options` (a plain `string[]`) when present. A flat list (empty `additional_options`) skips all of this — items are just left as whatever they are.
|
|
83
|
+
|
|
84
|
+
## `list` values in the Variables Editor's Values-tab JSON mode
|
|
85
|
+
|
|
86
|
+
On the wire (and in `default_value`), a `list` value is always a **JSON-encoded array packed into a string** — e.g. the string `["a","b"]`, not a nested array. Written naively into a JSON file, that means double-escaping: `"value": "[\"a\",\"b\"]"`.
|
|
87
|
+
|
|
88
|
+
To avoid making a human write that by hand, the Variables Editor's Values tab — both its JSON mode (`View/edit raw JSON`, including the Save/Import-to-file buttons) and the file it writes — allows `value` to be a **native JSON array** for `list`-type entries — `"value": ["a","b"]` — and converts at the display/parse boundary only (`toExportableValueRows`/`fromExportableValueRows` in `src/lib/variables-editor.ts`):
|
|
89
|
+
|
|
90
|
+
- **Display/export**: for any entry whose schema tag has `tag_type: "list"`, the stored string is `JSON.parse`'d back into a native array before it's shown in the JSON textarea or saved to a file, falling back to the raw string if it isn't valid JSON.
|
|
91
|
+
- **Parse/import**: the reverse — if `value` isn't a string, it's `JSON.stringify`'d immediately into MI's plain-string form before being sent anywhere.
|
|
92
|
+
- Everything in between — the `PUT /@api/variables/values` endpoint and `page-variables-diff.ts`'s export/validation logic — only ever sees plain strings; neither has any awareness of this convenience conversion.
|
|
93
|
+
|
|
94
|
+
## What MI's own "Create/Edit Variable" form actually shows
|
|
95
|
+
|
|
96
|
+
MI's schema-authoring UI is a hardcoded type switch, not generically schema-driven, so which fields it shows/asks for depends on `tag_type` (and, in one case, `tag_source`):
|
|
97
|
+
|
|
98
|
+
- **Name**: must match `/^[A-Za-z0-9_\s-]+$/` (letters, digits, underscore, whitespace, hyphen) and be unique — both enforced client-side before MI will save it.
|
|
99
|
+
- **`tag_source` picker**: shown only for `tag_type: "select"`/`"multiselect"`. Every other type is created as `static` with no way to pick a different source through this form.
|
|
100
|
+
- **`use_hmtl_editor_ind` ("Use WYSIWYG Editor")**: shown only for `tag_type: "text"`. Checking it forces `use_raw_html_ind`/`use_json_editor_ind` off (mutually exclusive).
|
|
101
|
+
- **`use_raw_html_ind` ("Raw HTML")** / **`use_json_editor_ind` ("Use JSON Editor")**: shown for `tag_type: "text"` or `"list"`; for `"text"`, only while WYSIWYG isn't checked. Not offered for `select`/`multiselect`/`file`/`color`/`boolean`.
|
|
102
|
+
- **`default_value`**: shown only for `tag_type: "text"` or `"list"`. There's no way to set a default through this form for `select`/`multiselect`/`file`/`color`/`boolean`.
|
|
103
|
+
- **`additional_options`**: shown for `text`/`file`/`list`/`color`, and for `select`/`multiselect` only when `tag_source` is `static`/`segment`/`element`/`dataset_data` (the sources whose options aren't loaded live). Never shown for `boolean`.
|
|
104
|
+
|
|
105
|
+
None of this is server-enforced (see below) — it's purely what the authoring form itself lets a human enter. A hand-written or MI-exported file can still legally contain combinations this form would never produce (e.g. a `default_value` on a `select` tag from an older export).
|
|
106
|
+
|
|
107
|
+
## `additional_options` per `tag_type`/`tag_source` — what MI's options-loading endpoint actually reads
|
|
108
|
+
|
|
109
|
+
The create-form's field visibility above is about what a human can *type into*; this is about what MI's backend actually *reads back out* when it needs to list a `select`/`multiselect` variable's options. The two don't always agree:
|
|
110
|
+
|
|
111
|
+
- **`select`/`multiselect`, `tag_source: "static"`**: `additional_options` **is** the option list — an array where each entry is either a plain string, or an object with `id`/`text`: `[{"id":"1","text":"One"},"Two"]`. A plain string entry uses itself as both the stored value and the label.
|
|
112
|
+
- **`select`/`multiselect`, `tag_source: "dataset_data"`**: `{dataset_id, key_column, text_column}` — MI pulls id/label pairs live from that dataset, using `key_column` for the id and `text_column` for the label.
|
|
113
|
+
- **`select`/`multiselect`, `tag_source: "element"`**: optional — `{"type": "metric" | "multi-metric chart" | "internal report" | "external report" | "other external content"}` narrows the dashboard-element list to one type. Omit it to list every element.
|
|
114
|
+
- **`select`/`multiselect`, `tag_source: "segment"`**: the create form shows this field for `segment`, but MI's options-loading endpoint never actually reads it for this source — the segment list always comes back unfiltered regardless of what's in `additional_options`. A form/backend inconsistency, not a feature to rely on.
|
|
115
|
+
- **`select`/`multiselect`, any other `tag_source`** (`dataset`, `announcement`, `group`, `category`, `custom_attribute`, `page`, `page_entity`): ignored entirely — MI queries its own live data for that source instead.
|
|
116
|
+
- **`list`**: see the dedicated section below (`ListItemFieldConfig[]`).
|
|
117
|
+
- **`text`/`file`/`color`**: the create form accepts input here, but no runtime consumer of it was found — treat as unused/reserved.
|
|
118
|
+
- **`boolean`**: not shown in the create form at all, and unused.
|
|
119
|
+
|
|
120
|
+
## Caveats for any pp-dev feature built on this
|
|
121
|
+
|
|
122
|
+
- `boolean` values are the literal strings `'true'`/`'false'` (confirmed against MI's own page-variable value editor — it renders a two-option radio group with exactly those values). MI performs no coercion, so a hand-edited or legacy file could still contain something else (`'Y'`/`'N'`, `'1'`/`'0'`) and MI would persist it as-is without complaint.
|
|
123
|
+
- `multiselect` values are stored as a single comma-joined string (e.g. `"a,b,c"`), not JSON — unlike `list`, which is JSON-encoded (see above).
|
|
124
|
+
- `file` values are just a filename string, with no schema-declared shape. MI's own upload control restricts the actual upload to images (`jpg`/`jpeg`/`png`/`gif`/`svg`) — a hand-set value of a different extension isn't rejected by anything server-side, just unlikely to render as an image. There's no public API (only whole-bundle asset zip download/upload — see above) for listing or uploading a page's individual file assets, so pp-dev's Variables Editor only offers a manual path input for this type, no browse/upload button.
|
|
125
|
+
- Because MI performs no type/enum validation server-side, any client-side (pp-dev) validation against `tag_type`/`additional_options` is a **best-effort convenience check**, not something MI itself guarantees or requires.
|
package/dist/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,33 @@
|
|
|
1
|
+
# [1.2.0-beta.3](https://github.com/mi-examples/pp-dev/compare/v1.2.0-beta.2...v1.2.0-beta.3) (2026-08-07)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* Variables Editor client script fails to parse, blanking the whole UI ([2e48b2e](https://github.com/mi-examples/pp-dev/commit/2e48b2e69c12124a6d300503a80b40f649de1316))
|
|
7
|
+
|
|
8
|
+
# [1.2.0-beta.2](https://github.com/mi-examples/pp-dev/compare/v1.2.0-beta.1...v1.2.0-beta.2) (2026-08-07)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* address CodeRabbit review feedback on PR [#227](https://github.com/mi-examples/pp-dev/issues/227) ([3f64e42](https://github.com/mi-examples/pp-dev/commit/3f64e42a9ffd213160fd14d300e0516099b8683d))
|
|
14
|
+
|
|
15
|
+
# [1.2.0-beta.1](https://github.com/mi-examples/pp-dev/compare/v1.1.1-beta.1...v1.2.0-beta.1) (2026-08-07)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* address npm audit vulnerabilities in root and test fixtures ([a33aad3](https://github.com/mi-examples/pp-dev/commit/a33aad3ca7a24078d6a8293ebe45e065baf62d0b))
|
|
21
|
+
* Variables Editor — ergonomic advanced-fields toggle, confirm before delete ([6cc96ee](https://github.com/mi-examples/pp-dev/commit/6cc96eef13dfeb12684e136e43ade115981a33d4))
|
|
22
|
+
* Variables Editor tab switch no longer blanks out until the fetch resolves ([399930d](https://github.com/mi-examples/pp-dev/commit/399930d4da7e1e846f52648cfeae9509b9c36402))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
* add Auto/Dark/Light theme switcher, shared across the dev panel, Inspector, and Variables Editor ([b6f72a6](https://github.com/mi-examples/pp-dev/commit/b6f72a68181105dd620db967307bd3e3575911fe))
|
|
28
|
+
* add page-variables API and schema/export/validation helpers ([36c727e](https://github.com/mi-examples/pp-dev/commit/36c727e7feeb45805ccae76984aaa755be2e8d7b))
|
|
29
|
+
* add standalone Variables Editor page with dev-panel entry points ([40bc88e](https://github.com/mi-examples/pp-dev/commit/40bc88e45fd9b25d4a6d47249ef791272ff92c20))
|
|
30
|
+
|
|
1
31
|
## [1.1.1-beta.1](https://github.com/mi-examples/pp-dev/compare/v1.1.0...v1.1.1-beta.1) (2026-07-27)
|
|
2
32
|
|
|
3
33
|
|
package/dist/README.md
CHANGED
|
@@ -18,6 +18,8 @@ lives of PP developers easier:
|
|
|
18
18
|
|
|
19
19
|
pp-dev is based on [Vite](https://vitejs.dev/).
|
|
20
20
|
|
|
21
|
+
📸 **[Feature tour](./docs/features.md)** — screenshots of the dev panel, Request Inspector, and Variables Editor.
|
|
22
|
+
|
|
21
23
|
## Installation
|
|
22
24
|
|
|
23
25
|
```bash
|
|
@@ -472,6 +474,8 @@ For custom build configuration, create a `vite.config` file. See [Vite Configura
|
|
|
472
474
|
|
|
473
475
|
pp-dev injects a floating dev panel into every served page. It shows the package name and version, the backend URL, the template mode and the App ID, and hosts the template **Sync** button. Since 1.0 the panel is fully repositionable and can be hidden.
|
|
474
476
|
|
|
477
|
+

|
|
478
|
+
|
|
475
479
|
### Position
|
|
476
480
|
|
|
477
481
|
The panel can be anchored to any of the four screen corners (default: bottom-right). Three ways to move it:
|
|
@@ -486,13 +490,17 @@ The minimize arrow, the panel's shadow, rounded corner and slide direction all m
|
|
|
486
490
|
|
|
487
491
|
Toggle **Auto-hide** in the settings popover (or set `devPanel.autoHide: true`). The panel slides behind the nearest screen edge leaving a 4px accent strip; hovering the strip for ~300 ms slides it out, and it hides again ~500 ms after the pointer leaves. Keyboard focus inside the panel keeps it revealed. While auto-hide is active the minimize arrow acts as a **pin** button that returns the panel to normal mode.
|
|
488
492
|
|
|
493
|
+
### Theme
|
|
494
|
+
|
|
495
|
+
The settings popover has an **Auto / Dark / Light** switcher. "Auto" follows the OS/browser preference; the other two force an override. The choice is shared (via the same `localStorage` key) with the standalone [Request Inspector](#request-inspector) and [Variables Editor](#variables-editor) pages, which also each have their own copy of the switcher for when they're opened directly without the panel present.
|
|
496
|
+
|
|
489
497
|
### Hiding and restoring
|
|
490
498
|
|
|
491
499
|
**Hide panel** in the settings popover (or `devPanel.hidden: true`) removes the panel from view entirely. To bring it back, open any page with `?pp-dev-panel=show` in the URL — the override persists across reloads. The symmetric `?pp-dev-panel=hide` hides it, which is handy for demos and clean screenshots.
|
|
492
500
|
|
|
493
501
|
### State persistence
|
|
494
502
|
|
|
495
|
-
Runtime choices are saved in the browser's `localStorage` (`pp-dev-info-position`, `pp-dev-info-auto-hide`, `pp-dev-info-hidden`) and take precedence over config values. **Reset to config defaults** in the settings popover clears all overrides. Storage is origin-scoped: overrides apply to every pp-dev app served on the same host and port, and a Metric Insights page that clears origin storage will reset them to config defaults.
|
|
503
|
+
Runtime choices are saved in the browser's `localStorage` (`pp-dev-info-position`, `pp-dev-info-auto-hide`, `pp-dev-info-hidden`, `pp-dev-info-theme`) and take precedence over config values. **Reset to config defaults** in the settings popover clears all overrides. Storage is origin-scoped: overrides apply to every pp-dev app served on the same host and port, and a Metric Insights page that clears origin storage will reset them to config defaults.
|
|
496
504
|
|
|
497
505
|
### Configuration
|
|
498
506
|
|
|
@@ -509,6 +517,33 @@ export default defineConfig({
|
|
|
509
517
|
|
|
510
518
|
See the [`devPanel` option reference](#devpanel--dev-panel-appearance) for details.
|
|
511
519
|
|
|
520
|
+
### Page variables
|
|
521
|
+
|
|
522
|
+
For pages with a template (`app.type: 'template'`), the settings popover has:
|
|
523
|
+
|
|
524
|
+
- **Reload variables** — refetches the page's live variable values from MI right now (bypassing the usual request-level cache) and reloads the page, so `[VarName]` substitution reflects a just-saved value without restarting the dev server.
|
|
525
|
+
- **Open variables editor…** — opens the standalone [Variables Editor](#variables-editor) page.
|
|
526
|
+
|
|
527
|
+
Pages without a template (`app.type: 'page'`) have no variables, so this group — and the button that opens the editor — is hidden.
|
|
528
|
+
|
|
529
|
+
### Variables Editor
|
|
530
|
+
|
|
531
|
+
A standalone page at `/@pp-dev/variables-editor`, alongside the [Request Inspector](#request-inspector), with two tabs:
|
|
532
|
+
|
|
533
|
+
- **Schema** — view/edit the template's `__template_variables.json` (add/remove variables, change type, default, `additional_options`, etc.), with a raw-JSON escape hatch.
|
|
534
|
+
|
|
535
|
+

|
|
536
|
+
|
|
537
|
+
- **Values** — edit the page's live variable values in place, with type-aware widgets (searchable select for `static` options, a per-item form for `list`, …). A JSON mode (`View/edit raw JSON`) shows/accepts the same values as plain JSON — list-type values as native arrays, not double-escaped strings — with **Save to JSON file…** / **Import from JSON file…** buttons, and flags values that don't match a declared option, changed since the last load, or aren't in the schema.
|
|
538
|
+
|
|
539
|
+

|
|
540
|
+
|
|
541
|
+
Both the active tab and Values' JSON mode are reflected in the URL (`?tab=values&mode=json`), so a specific view can be bookmarked or shared.
|
|
542
|
+
|
|
543
|
+
See the [feature tour](./docs/features.md#variables-editor) for more screenshots, including the advanced/raw-JSON views and the theme switcher.
|
|
544
|
+
|
|
545
|
+
See [`TEMPLATE_VARIABLES.md`](./TEMPLATE_VARIABLES.md) — also shipped inside the published package — for the `__template_variables.json` schema this feature reads.
|
|
546
|
+
|
|
512
547
|
## Request Inspector
|
|
513
548
|
|
|
514
549
|
pp-dev includes a built-in request inspector that captures every proxied and locally-served HTTP request made during development. It is enabled by default.
|
|
@@ -521,6 +556,12 @@ Open `http://localhost:3000/@pp-dev/inspector` (replace port as needed) in any b
|
|
|
521
556
|
- Full request and response headers, with a **Copy** button per section
|
|
522
557
|
- Request and response bodies rendered as text for JSON/HTML/CSS/plain-text content types, with **Copy** and **Save** buttons
|
|
523
558
|
- Binary bodies (images, fonts, archives) show metadata only and offer a **Save** button
|
|
559
|
+
|
|
560
|
+

|
|
561
|
+
|
|
562
|
+
Selecting a request opens the detail pane with headers and a syntax-highlighted body:
|
|
563
|
+
|
|
564
|
+

|
|
524
565
|
- A **Clear** button in the top-right removes all stored entries
|
|
525
566
|
|
|
526
567
|
### Source badges
|