ngx-json-render 0.9.0 → 0.9.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-json-render",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
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",
@@ -28,7 +28,8 @@
28
28
  "zod": "^4.0.0",
29
29
  "@modelcontextprotocol/ext-apps": "^1.7.5",
30
30
  "@modelcontextprotocol/sdk": "^1.29.0",
31
- "@json-render/devtools": ">=0.20.0 <0.22.0"
31
+ "@json-render/devtools": ">=0.20.0 <0.22.0",
32
+ "@angular/router": ">=19.0.0"
32
33
  },
33
34
  "peerDependenciesMeta": {
34
35
  "@modelcontextprotocol/ext-apps": {
@@ -39,6 +40,9 @@
39
40
  },
40
41
  "@json-render/devtools": {
41
42
  "optional": true
43
+ },
44
+ "@angular/router": {
45
+ "optional": true
42
46
  }
43
47
  },
44
48
  "dependencies": {
@@ -67,6 +71,10 @@
67
71
  "types": "./types/ngx-json-render-mcp.d.ts",
68
72
  "default": "./fesm2022/ngx-json-render-mcp.mjs"
69
73
  },
74
+ "./router": {
75
+ "types": "./types/ngx-json-render-router.d.ts",
76
+ "default": "./fesm2022/ngx-json-render-router.mjs"
77
+ },
70
78
  "./schema": {
71
79
  "types": "./types/ngx-json-render-schema.d.ts",
72
80
  "default": "./fesm2022/ngx-json-render-schema.mjs"
@@ -0,0 +1,39 @@
1
+ /** Which paths a spec may send the app to. */
2
+ interface RouterNavigateOptions {
3
+ /**
4
+ * The paths a spec may navigate to. A string must equal the path exactly; a
5
+ * `RegExp` is tested against it; a function decides on its own. The path is
6
+ * what comes before any `?` or `#`, so a query string or fragment neither
7
+ * helps nor hurts a match, and is passed on to the router as written.
8
+ *
9
+ * Required: a spec is model output, and the app is what knows which of its
10
+ * routes a generated UI has any business opening.
11
+ */
12
+ readonly allow: readonly (string | RegExp)[] | ((path: string) => boolean);
13
+ }
14
+ /**
15
+ * A `navigate` for `<json-render>` that hands a spec's
16
+ * `onSuccess: { navigate }` path to the Angular `Router`, but only a path
17
+ * inside the app that `allow` lets through. Anything else is refused with a
18
+ * warning and goes nowhere.
19
+ *
20
+ * Call it in an injection context — in the function form of
21
+ * `provideJsonRender`, or in a field initializer:
22
+ *
23
+ * ```ts
24
+ * provideJsonRender(() => ({
25
+ * registry,
26
+ * navigate: injectRouterNavigate({ allow: ['/thanks', /^\/orders\/\d+$/] }),
27
+ * }));
28
+ * ```
29
+ *
30
+ * Whatever `allow` says, a path is refused unless it starts with a single
31
+ * `/`: no other origin (`https://…`, `//host`), no scheme (`javascript:…`),
32
+ * no path relative to wherever the user happens to be. A backslash or a
33
+ * control character refuses it too, since browsers read `/\host` as
34
+ * `//host`.
35
+ */
36
+ declare function injectRouterNavigate(options: RouterNavigateOptions): (path: string) => void;
37
+
38
+ export { injectRouterNavigate };
39
+ export type { RouterNavigateOptions };
@@ -2,7 +2,7 @@ import * as _json_render_core from '@json-render/core';
2
2
  import { ResolvedAction, ActionHandler, ActionBinding, SpecIssue, Spec, Catalog, InferCatalogActions, InferActionParams, StateModel, InferCatalogComponents, UIElement, StateStore, ValidationFunction, ComputedFunction, DirectiveDefinition, ActionConfirm, DirectiveRegistry, ValidationResult, ValidationConfig, JsonPatch, FlatElement } from '@json-render/core';
3
3
  export { ActionBinding, ActionHandler, InferActionParams, InferCatalogComponents, InferComponentProps, JsonPatch, Spec, SpecIssue, StateModel, StateStore, UIElement, VisibilityCondition, autoFixSpec, createStateStore, formatSpecIssues, nestedToFlat, validateSpec } from '@json-render/core';
4
4
  import * as _angular_core from '@angular/core';
5
- import { Signal, Type, Injector, InjectionToken } from '@angular/core';
5
+ import { Signal, Type, Injector, InjectionToken, Provider } from '@angular/core';
6
6
  import * as ngx_json_render from 'ngx-json-render';
7
7
  export { AngularSchema, AngularSpec, schema } from 'ngx-json-render/schema';
8
8
 
@@ -478,8 +478,11 @@ declare function injectBoundProp<T>(propValue: () => T | undefined, bindingPath:
478
478
  declare class JsonRenderer {
479
479
  /** The UI spec to render (may be partial while streaming). */
480
480
  readonly spec: _angular_core.InputSignal<Spec | null>;
481
- /** Component registry mapping catalog type names to Angular components. */
482
- readonly registry: _angular_core.InputSignal<ComponentRegistry>;
481
+ /**
482
+ * Component registry mapping catalog type names to Angular components.
483
+ * Required unless a {@link provideJsonRender} above supplies one.
484
+ */
485
+ readonly registry: _angular_core.InputSignal<ComponentRegistry | undefined>;
483
486
  /** Whether the spec is currently loading/streaming. */
484
487
  readonly loading: _angular_core.InputSignal<boolean>;
485
488
  /** Fallback component for unknown types. */
@@ -496,7 +499,7 @@ declare class JsonRenderer {
496
499
  * The check is skipped while `loading` is true: a spec that is still
497
500
  * arriving is expected to reference children that have not streamed in yet.
498
501
  */
499
- readonly validate: _angular_core.InputSignal<SpecValidationMode>;
502
+ readonly validate: _angular_core.InputSignal<SpecValidationMode | undefined>;
500
503
  /**
501
504
  * Caps on what the spec may cost the browser: `maxElements`, `maxDepth` and
502
505
  * `maxRepeatItems`. Unset by default, and each field is independently
@@ -553,6 +556,15 @@ declare class JsonRenderer {
553
556
  readonly stateStore: JsonRenderStateService;
554
557
  /** The action dispatcher of this renderer. */
555
558
  protected readonly actions: JsonRenderActionsService;
559
+ /**
560
+ * The nearest {@link provideJsonRender}'s defaults. Every option input
561
+ * falls through to these when left `null` or `undefined`; see
562
+ * {@link JsonRenderConfig} for the merge rules.
563
+ */
564
+ private readonly config;
565
+ private readonly mode;
566
+ private readonly limits;
567
+ private readonly specCatalog;
556
568
  /**
557
569
  * The spec as checked, and what the check found. While `loading`, the mode
558
570
  * is forced off: the spec is still arriving, and the missing children it
@@ -577,7 +589,7 @@ declare class JsonRenderer {
577
589
  */
578
590
  protected readonly confirmInjector: _angular_core.Signal<Injector | null>;
579
591
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<JsonRenderer, never>;
580
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<JsonRenderer, "json-render", never, { "spec": { "alias": "spec"; "required": true; "isSignal": true; }; "registry": { "alias": "registry"; "required": true; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "fallback": { "alias": "fallback"; "required": false; "isSignal": true; }; "validate": { "alias": "validate"; "required": false; "isSignal": true; }; "renderLimits": { "alias": "renderLimits"; "required": false; "isSignal": true; }; "catalog": { "alias": "catalog"; "required": false; "isSignal": true; }; "state": { "alias": "state"; "required": false; "isSignal": true; }; "store": { "alias": "store"; "required": false; "isSignal": true; }; "handlers": { "alias": "handlers"; "required": false; "isSignal": true; }; "onAction": { "alias": "onAction"; "required": false; "isSignal": true; }; "navigate": { "alias": "navigate"; "required": false; "isSignal": true; }; "validationFunctions": { "alias": "validationFunctions"; "required": false; "isSignal": true; }; "functions": { "alias": "functions"; "required": false; "isSignal": true; }; "directives": { "alias": "directives"; "required": false; "isSignal": true; }; }, { "stateChange": "stateChange"; }, never, never, true, never>;
592
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<JsonRenderer, "json-render", never, { "spec": { "alias": "spec"; "required": true; "isSignal": true; }; "registry": { "alias": "registry"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "fallback": { "alias": "fallback"; "required": false; "isSignal": true; }; "validate": { "alias": "validate"; "required": false; "isSignal": true; }; "renderLimits": { "alias": "renderLimits"; "required": false; "isSignal": true; }; "catalog": { "alias": "catalog"; "required": false; "isSignal": true; }; "state": { "alias": "state"; "required": false; "isSignal": true; }; "store": { "alias": "store"; "required": false; "isSignal": true; }; "handlers": { "alias": "handlers"; "required": false; "isSignal": true; }; "onAction": { "alias": "onAction"; "required": false; "isSignal": true; }; "navigate": { "alias": "navigate"; "required": false; "isSignal": true; }; "validationFunctions": { "alias": "validationFunctions"; "required": false; "isSignal": true; }; "functions": { "alias": "functions"; "required": false; "isSignal": true; }; "directives": { "alias": "directives"; "required": false; "isSignal": true; }; }, { "stateChange": "stateChange"; }, never, never, true, never>;
581
593
  }
582
594
 
583
595
  /**
@@ -888,6 +900,62 @@ declare const JR_CONFIRM_DIALOG: InjectionToken<Type<unknown>>;
888
900
  /** Inject the confirmation a replacement dialog component is rendering for. */
889
901
  declare function injectConfirmContext(): ConfirmContext;
890
902
 
903
+ /**
904
+ * Renderer defaults for every `<json-render>` below a provider: each field is
905
+ * the input of the same name.
906
+ *
907
+ * An input bound on the element wins over the provided value, and a value
908
+ * left `null` or `undefined` on the element falls through to it. Named
909
+ * vocabularies — `handlers`, `functions`, `validationFunctions` and
910
+ * `directives` — merge by name instead, the element's entry winning a name
911
+ * both define. Everything else replaces: a `registry` belongs to its catalog,
912
+ * so two are never mixed behind your back (spread them yourself to combine).
913
+ */
914
+ interface JsonRenderConfig {
915
+ registry?: ComponentRegistry;
916
+ fallback?: Type<unknown> | RegistryEntry | null;
917
+ validate?: SpecValidationMode;
918
+ renderLimits?: RenderLimits | null;
919
+ catalog?: SpecCatalog | null;
920
+ handlers?: Record<string, ActionHandler>;
921
+ onAction?: ((name: string, params?: Record<string, unknown>) => unknown) | null;
922
+ navigate?: ((path: string) => void) | null;
923
+ validationFunctions?: Record<string, ValidationFunction>;
924
+ functions?: Record<string, ComputedFunction>;
925
+ directives?: DirectiveDefinition<any>[];
926
+ }
927
+ /**
928
+ * The defaults the nearest {@link provideJsonRender} supplies, already merged
929
+ * with any provider above it.
930
+ */
931
+ declare const JSON_RENDER_CONFIG: InjectionToken<JsonRenderConfig>;
932
+ /**
933
+ * Set renderer defaults once instead of on every `<json-render>`:
934
+ *
935
+ * ```ts
936
+ * bootstrapApplication(App, { providers: [provideJsonRender({ registry })] });
937
+ * ```
938
+ *
939
+ * ```html
940
+ * <json-render [spec]="m.spec" />
941
+ * ```
942
+ *
943
+ * Pass a function to build the defaults with `inject()`, for handlers that
944
+ * call your services:
945
+ *
946
+ * ```ts
947
+ * provideJsonRender(() => {
948
+ * const orders = inject(OrderService);
949
+ * return { registry, handlers: { cancelOrder: (p) => orders.cancel(p['id']) } };
950
+ * });
951
+ * ```
952
+ *
953
+ * Works in application, route and component `providers`. A provider below
954
+ * another extends it with the same rules an element input does: its own
955
+ * values replace, its named vocabularies merge.
956
+ */
957
+ declare function provideJsonRender(config: JsonRenderConfig | (() => JsonRenderConfig)): Provider[];
958
+
891
959
  /**
892
960
  * The render context of the element currently being rendered.
893
961
  * Provided by the renderer for every catalog component instance.
@@ -1417,5 +1485,5 @@ declare function injectChatUI(options: ChatUIOptions): ChatUIReturn;
1417
1485
  */
1418
1486
  declare function injectDevtoolsActive(): Signal<boolean>;
1419
1487
 
1420
- export { CONFIRM_CONTEXT, ELEMENT_KEY, JR_CONFIRM_DIALOG, JR_CONFIRM_LABELS, JrChildren, JrConfirmDialog, JrElement, JrRepeatScope, JsonRenderActionsService, JsonRenderRootContext, JsonRenderStateService, JsonRenderValidationService, JsonRenderer, RENDER_CONTEXT, REPEAT_SCOPE, applyPatch, buildSpecFromParts, checkSpec, createStoreSetState, defineRegistry, flatToTree, formatSpecCheckIssues, getTextFromParts, injectAction, injectActions, injectBoundProp, injectChatUI, injectConfirmContext, injectDevtoolsActive, injectElementKey, injectFieldValidation, injectRenderContext, injectRepeatScope, injectStateBinding, injectStateStore, injectStateValue, injectUIStream, injectValidation, isActionCancelled, jsonRenderMessage, ɵregisterStreamObserver };
1421
- export type { ActionFn, Actions, CatalogHasActions, ChatMessage, ChatUIOptions, ChatUIReturn, ComponentRegistry, Components, ConfirmContext, ConfirmLabels, DataPart, DefineRegistryResult, EventHandle, FieldValidationState, PendingConfirmation, RegistryEntry, RenderContext, RenderLimits, RepeatScope, SetState, SpecCatalog, SpecCheck, SpecCheckIssue, SpecCheckIssueCode, SpecCheckOptions, SpecValidationMode, StateChange, StreamObserver, StreamObserverUsage, TokenUsage, UIStreamOptions, UIStreamReturn, UIStreamSendOptions };
1488
+ export { CONFIRM_CONTEXT, ELEMENT_KEY, JR_CONFIRM_DIALOG, JR_CONFIRM_LABELS, JSON_RENDER_CONFIG, JrChildren, JrConfirmDialog, JrElement, JrRepeatScope, JsonRenderActionsService, JsonRenderRootContext, JsonRenderStateService, JsonRenderValidationService, JsonRenderer, RENDER_CONTEXT, REPEAT_SCOPE, applyPatch, buildSpecFromParts, checkSpec, createStoreSetState, defineRegistry, flatToTree, formatSpecCheckIssues, getTextFromParts, injectAction, injectActions, injectBoundProp, injectChatUI, injectConfirmContext, injectDevtoolsActive, injectElementKey, injectFieldValidation, injectRenderContext, injectRepeatScope, injectStateBinding, injectStateStore, injectStateValue, injectUIStream, injectValidation, isActionCancelled, jsonRenderMessage, provideJsonRender, ɵregisterStreamObserver };
1489
+ export type { ActionFn, Actions, CatalogHasActions, ChatMessage, ChatUIOptions, ChatUIReturn, ComponentRegistry, Components, ConfirmContext, ConfirmLabels, DataPart, DefineRegistryResult, EventHandle, FieldValidationState, JsonRenderConfig, PendingConfirmation, RegistryEntry, RenderContext, RenderLimits, RepeatScope, SetState, SpecCatalog, SpecCheck, SpecCheckIssue, SpecCheckIssueCode, SpecCheckOptions, SpecValidationMode, StateChange, StreamObserver, StreamObserverUsage, TokenUsage, UIStreamOptions, UIStreamReturn, UIStreamSendOptions };