ngx-json-render 0.1.2 → 0.1.3

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.
Files changed (2) hide show
  1. package/README.md +51 -1
  2. package/package.json +5 -4
package/README.md CHANGED
@@ -6,6 +6,8 @@ Angular renderer for [json-render](https://github.com/vercel-labs/json-render)
6
6
 
7
7
  Built on `@json-render/core` (the same spec format, expressions, state store, actions, and streaming compiler used by the React, Vue, Solid, and Svelte renderers) and idiomatic modern Angular: standalone components, signals, zoneless-friendly, `OnPush` everywhere.
8
8
 
9
+ This is an Angular **adapter over the official core**, not a second implementation of it — `@json-render/core` is a peer dependency, and the spec your model emits is the same one the React, Vue, Solid and Svelte renderers consume. A catalog and a spec written here move to another framework unchanged.
10
+
9
11
  **[Live demo](https://shteynu.github.io/ngx-json-render/)** — interactive spec (bindings, repeat, confirm, watch) and a replayable SpecStream showing progressive rendering ([source](https://github.com/shteynu/ngx-json-render/tree/main/projects/demo)) — or [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/shteynu/ngx-json-render)
10
12
 
11
13
  ![A SpecStream of RFC 6902 patches rendering progressively into an Angular dashboard](https://raw.githubusercontent.com/shteynu/ngx-json-render/main/docs/streaming.gif)
@@ -16,7 +18,7 @@ Built on `@json-render/core` (the same spec format, expressions, state store, ac
16
18
  npm install ngx-json-render @json-render/core zod
17
19
  ```
18
20
 
19
- Requires Angular ≥ 21.
21
+ Requires Angular ≥ 20.
20
22
 
21
23
  ## Quick start
22
24
 
@@ -219,6 +221,54 @@ Share one store across renderers (or drive it from your own state management) by
219
221
 
220
222
  If a catalog component renders `<input [value]="ctx.props().value">`, remember that one-way bindings do not re-assert the DOM when the bound value returns to its previously applied value while the user typed in between (e.g. `pushState` + `clearStatePath`). Sync imperatively instead — see `InputComponent` in the demo app for the pattern.
221
223
 
224
+ ## Security
225
+
226
+ Specs are attacker-shaped input: whatever produced one — a model, a prompt, a
227
+ user's text inside that prompt — is not something you control. The renderer is
228
+ built so that a hostile spec cannot execute code, but it can still act within
229
+ the authority you hand it. What follows is what the renderer guarantees and
230
+ what stays your responsibility.
231
+
232
+ **A spec cannot execute code.** There is no `eval`, no `Function` constructor,
233
+ and no `innerHTML`/`bypassSecurityTrust` anywhere in this package or in
234
+ `@json-render/core`. Expressions (`$state`, `$item`, `$index`, `$bindState`)
235
+ are interpreted against the state model, not evaluated as JavaScript, and all
236
+ text reaches the DOM through Angular interpolation. Script injection through a
237
+ spec is not a thing you have to defend against.
238
+
239
+ **A spec can only name actions you registered.** Built-ins (`setState`,
240
+ `pushState`, `removeState`, `push`, `pop`, `validateForm`) are handled inside
241
+ the renderer; every other action name is looked up in the `handlers` you pass.
242
+ An unrecognised name logs a warning and does nothing.
243
+
244
+ The exception is `onAction`, which is a deliberate catch-all: when you pass it,
245
+ **every** action name in the spec reaches it, including ones you never put in
246
+ your catalog. If you use it, switch on the names you expect and ignore the
247
+ rest.
248
+
249
+ **A spec chooses its own state paths.** `setState`, `pushState`, `removeState`
250
+ and `onSuccess.set` all take a `statePath` straight from the spec, so a
251
+ generated UI can write anywhere in the state model it is rendered against —
252
+ and `push`/`pop` write `/currentScreen` and `/navStack`. In controlled mode
253
+ this is *your* store. Give the renderer a store scoped to the generated view
254
+ rather than the one holding session, entitlement or billing state.
255
+
256
+ **A spec chooses the navigation target.** `onSuccess: { navigate }` passes its
257
+ string to the `navigate` callback you provide, verbatim. Treat it as untrusted:
258
+ match it against known routes, and never hand it to `window.location` or
259
+ `router.navigateByUrl` unchecked.
260
+
261
+ **A spec sizes its own render tree.** `repeat` iterates a state array the spec
262
+ may itself have supplied, so specs are a denial-of-service surface against the
263
+ browser tab. Cap spec size and array lengths at the boundary where you accept
264
+ one.
265
+
266
+ **`confirm` is a UX affordance, not a security control.** It routes an action
267
+ through the confirmation dialog before the handler runs, but it is set on the
268
+ action binding *inside the spec* (`on.press.confirm`) — so the same party that
269
+ chose the action also chose whether to ask. Real authorization belongs in the
270
+ handler, on the server.
271
+
222
272
  ## API surface
223
273
 
224
274
  Components: `JsonRenderer` (`<json-render>`), `JrChildren`, `JrConfirmDialog`, `JrElement`, `JrRepeatScope`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-json-render",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Angular renderer for json-render — stream AI-generated JSON specs into real Angular components with signals.",
5
5
  "keywords": [
6
6
  "angular",
@@ -22,11 +22,12 @@
22
22
  "url": "https://github.com/shteynu/ngx-json-render/issues"
23
23
  },
24
24
  "peerDependencies": {
25
- "@angular/common": ">=21.0.0",
26
- "@angular/core": ">=21.0.0"
25
+ "@angular/common": ">=20.0.0",
26
+ "@angular/core": ">=20.0.0",
27
+ "@json-render/core": "^0.20.0",
28
+ "zod": "^4.0.0"
27
29
  },
28
30
  "dependencies": {
29
- "@json-render/core": "^0.20.0",
30
31
  "tslib": "^2.3.0"
31
32
  },
32
33
  "sideEffects": false,