@bonsae/nrg 0.18.4 → 0.19.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/README.md +38 -45
- package/package.json +1 -1
- package/server/index.cjs +96 -10
- package/server/resources/nrg-client.js +2269 -2233
- package/test/client/component/config.js +11 -0
- package/test/client/component/index.js +218 -235
- package/test/client/component/nrg.css +1 -0
- package/test/client/component/setup.js +1549 -140
- package/test/client/e2e/index.js +721 -367
- package/test/client/unit/index.js +204 -16
- package/test/client/unit/setup.js +209 -19
- package/test/server/unit/index.js +25 -4
- package/tsconfig/core/client.json +1 -1
- package/tsconfig/test/client/component.json +1 -1
- package/types/client.d.ts +98 -18
- package/types/server.d.ts +50 -12
- package/types/shims/brands.d.ts +32 -0
- package/types/shims/{form → client/form}/components/node-red-editor-input.vue.d.ts +1 -1
- package/types/shims/{form → client/form}/components/node-red-json-schema-form.vue.d.ts +21 -2
- package/types/shims/{form → client/form}/components/node-red-select-input.vue.d.ts +1 -0
- package/types/shims/{form → client/form}/components/node-red-typed-input.vue.d.ts +1 -0
- package/types/shims/client/types.d.ts +206 -0
- package/types/shims/components.d.ts +8 -8
- package/types/shims/constants.d.ts +4 -0
- package/types/shims/schema-options.d.ts +23 -10
- package/types/shims/typebox.d.ts +2 -2
- package/types/test-client-component.d.ts +170 -55
- package/types/test-client-e2e.d.ts +50 -0
- package/types/test-client-unit.d.ts +86 -22
- package/types/test-server-unit.d.ts +3 -1
- package/types/vite.d.ts +38 -9
- package/vite/index.js +733 -528
- /package/types/shims/{form → client/form}/components/node-red-config-input.vue.d.ts +0 -0
- /package/types/shims/{form → client/form}/components/node-red-input-label.vue.d.ts +0 -0
- /package/types/shims/{form → client/form}/components/node-red-input.vue.d.ts +0 -0
- /package/types/shims/{form → client/form}/components/node-red-toggle.vue.d.ts +0 -0
- /package/types/shims/{globals.d.ts → client/globals.d.ts} +0 -0
package/types/client.d.ts
CHANGED
|
@@ -1,12 +1,36 @@
|
|
|
1
1
|
// Generated by dts-bundle-generator v9.5.1
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { Static, TSchema } from '@sinclair/typebox';
|
|
4
|
+
import { SchemaObject } from 'ajv';
|
|
4
5
|
import { App, Component } from 'vue';
|
|
5
6
|
|
|
6
7
|
interface NodeRefResolved<T = any> {
|
|
7
8
|
readonly __nrg_node_ref: true;
|
|
8
9
|
readonly __instance: T;
|
|
9
10
|
}
|
|
11
|
+
interface TypedInputResolved {
|
|
12
|
+
resolve(...args: any[]): any;
|
|
13
|
+
value: unknown;
|
|
14
|
+
type: string;
|
|
15
|
+
}
|
|
16
|
+
interface JsonSchemaObjectExtensions {
|
|
17
|
+
format?: "node-id" | "flow-id" | "topic-path" | (string & {});
|
|
18
|
+
/** expose this settings property to the editor via RED.settings */
|
|
19
|
+
exportable?: boolean;
|
|
20
|
+
/** set by SchemaType.NodeRef — the referenced config node type */
|
|
21
|
+
"x-nrg-node-type"?: string;
|
|
22
|
+
/** set by SchemaType.TypedInput — marks a TypedInput value/type pair */
|
|
23
|
+
"x-nrg-typed-input"?: boolean;
|
|
24
|
+
/** set by markNonValidatable — ajv skips this property */
|
|
25
|
+
"x-nrg-skip-validation"?: boolean;
|
|
26
|
+
/** form rendering hints consumed by the auto-generated editor form */
|
|
27
|
+
"x-nrg-form"?: {
|
|
28
|
+
icon?: string;
|
|
29
|
+
typedInputTypes?: string[];
|
|
30
|
+
editorLanguage?: string;
|
|
31
|
+
toggle?: boolean;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
10
34
|
export interface NodeStateCredentials {
|
|
11
35
|
[key: string]: any;
|
|
12
36
|
}
|
|
@@ -68,6 +92,18 @@ export interface NodeRedNode {
|
|
|
68
92
|
_newState?: NodeRedNode;
|
|
69
93
|
_app?: App | null;
|
|
70
94
|
_: (str: string) => string;
|
|
95
|
+
/** dynamic port count (base outputs + enabled built-in ports) */
|
|
96
|
+
outputs?: number;
|
|
97
|
+
/** injected when the node has an inputSchema */
|
|
98
|
+
validateInput?: boolean;
|
|
99
|
+
/** injected when the node has an outputsSchema */
|
|
100
|
+
validateOutput?: boolean;
|
|
101
|
+
/** present when the node's configSchema declares SchemaType.ReturnProperty() */
|
|
102
|
+
returnProperty?: string;
|
|
103
|
+
/** built-in port toggles, present when declared in the configSchema */
|
|
104
|
+
errorPort?: boolean;
|
|
105
|
+
completePort?: boolean;
|
|
106
|
+
statusPort?: boolean;
|
|
71
107
|
[key: string]: any;
|
|
72
108
|
}
|
|
73
109
|
export interface NodeDefinition {
|
|
@@ -92,6 +128,56 @@ export interface NodeDefinition {
|
|
|
92
128
|
onPaletteRemove?: (this: NodeRedNode) => void;
|
|
93
129
|
form?: NodeFormDefinition;
|
|
94
130
|
}
|
|
131
|
+
/** Form rendering hints carried by the `x-nrg-form` schema keyword. */
|
|
132
|
+
export type NrgFormOptions = NonNullable<JsonSchemaObjectExtensions["x-nrg-form"]>;
|
|
133
|
+
/**
|
|
134
|
+
* A serialized property schema inside {@link JsonSchemaObject} `properties`,
|
|
135
|
+
* including NRG's custom keywords (shared vocabulary in core/schema-options)
|
|
136
|
+
* that drive form rendering and NodeRef/TypedInput identification.
|
|
137
|
+
*/
|
|
138
|
+
export interface JsonPropertySchema extends JsonSchemaObjectExtensions {
|
|
139
|
+
type?: string | string[];
|
|
140
|
+
properties?: Record<string, JsonPropertySchema>;
|
|
141
|
+
required?: string[];
|
|
142
|
+
enum?: unknown[];
|
|
143
|
+
anyOf?: JsonPropertySchema[];
|
|
144
|
+
const?: unknown;
|
|
145
|
+
items?: JsonPropertySchema;
|
|
146
|
+
title?: string;
|
|
147
|
+
description?: string;
|
|
148
|
+
default?: unknown;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* A serialized JSON Schema object as the build pipeline emits it (never a
|
|
152
|
+
* live TypeBox instance). Extends ajv's `SchemaObject` so it flows into
|
|
153
|
+
* validator APIs without casts, while keeping the `type: "object"`
|
|
154
|
+
* discriminant and structured `properties`/`required` that ajv's open
|
|
155
|
+
* `[x: string]: any` shape does not provide.
|
|
156
|
+
*/
|
|
157
|
+
export interface JsonSchemaObject extends SchemaObject {
|
|
158
|
+
type: "object";
|
|
159
|
+
properties?: Record<string, JsonPropertySchema>;
|
|
160
|
+
required?: string[];
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* A node definition as it exists at editor runtime, after the build pipeline
|
|
164
|
+
* merged in the schema-derived artifacts (defaults, credentials, serialized
|
|
165
|
+
* schemas). Authors write {@link NodeDefinition}; the inliner provides the
|
|
166
|
+
* rest.
|
|
167
|
+
*/
|
|
168
|
+
export interface RuntimeNodeDefinition extends NodeDefinition {
|
|
169
|
+
defaults?: NodeDefaults;
|
|
170
|
+
credentials?: NodeCredentials;
|
|
171
|
+
configSchema?: JsonSchemaObject;
|
|
172
|
+
credentialsSchema?: JsonSchemaObject;
|
|
173
|
+
inputSchema?: JsonSchemaObject;
|
|
174
|
+
/**
|
|
175
|
+
* Single port, positional ports, or named ports (key = port name).
|
|
176
|
+
* Not constrained to object schemas: with returnProperty the raw sent
|
|
177
|
+
* value is validated, so results may be any schema shape.
|
|
178
|
+
*/
|
|
179
|
+
outputsSchema?: JsonPropertySchema | JsonPropertySchema[] | Record<string, JsonPropertySchema>;
|
|
180
|
+
}
|
|
95
181
|
export interface NodeDefaults {
|
|
96
182
|
[key: string]: {
|
|
97
183
|
value: any;
|
|
@@ -109,16 +195,6 @@ export interface NodeCredentials {
|
|
|
109
195
|
required?: boolean;
|
|
110
196
|
};
|
|
111
197
|
}
|
|
112
|
-
export interface MergedNodeDefinition extends NodeDefinition {
|
|
113
|
-
defaults?: NodeDefaults;
|
|
114
|
-
credentials?: NodeCredentials;
|
|
115
|
-
configSchema?: Record<string, any>;
|
|
116
|
-
credentialsSchema?: {
|
|
117
|
-
properties?: Record<string, any>;
|
|
118
|
-
};
|
|
119
|
-
outputsSchema?: Record<string, any>;
|
|
120
|
-
inputSchema?: Record<string, any>;
|
|
121
|
-
}
|
|
122
198
|
export interface NodeFeatures {
|
|
123
199
|
hasInputSchema: boolean;
|
|
124
200
|
hasOutputSchema: boolean;
|
|
@@ -128,12 +204,16 @@ export interface TypedInputValue {
|
|
|
128
204
|
value: string;
|
|
129
205
|
type: string;
|
|
130
206
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
207
|
+
/**
|
|
208
|
+
* Maps a schema's static type to the raw values the editor form holds.
|
|
209
|
+
* The server counterpart (`ResolvedStatic` in server/schemas/types) maps the
|
|
210
|
+
* same brands — shared via core/brands — to resolved runtime values instead.
|
|
211
|
+
* - `NodeRef<T>` → `string` (the referenced node's id)
|
|
212
|
+
* - `TypedInput<T>` → `TypedInputValue` (raw value + type pair)
|
|
213
|
+
* - Functions pass through, arrays and objects map recursively
|
|
214
|
+
*/
|
|
215
|
+
export type EditorStatic<T> = T extends NodeRefResolved<any> ? string : T extends TypedInputResolved ? TypedInputValue : T extends (...args: any[]) => any ? T : T extends Array<infer I> ? EditorStatic<I>[] : T extends object ? {
|
|
216
|
+
[K in keyof T]: EditorStatic<T[K]>;
|
|
137
217
|
} : T;
|
|
138
218
|
/**
|
|
139
219
|
* Infers the client-side TypeScript type from a TypeBox schema.
|
|
@@ -151,7 +231,7 @@ type _ToClient<T> = T extends NodeRefResolved<any> ? string : T extends {
|
|
|
151
231
|
* type Config = Infer<typeof ConfigSchema>;
|
|
152
232
|
* ```
|
|
153
233
|
*/
|
|
154
|
-
export type Infer<T extends TSchema> =
|
|
234
|
+
export type Infer<T extends TSchema> = EditorStatic<Static<T>>;
|
|
155
235
|
|
|
156
236
|
export {};
|
|
157
237
|
|
package/types/server.d.ts
CHANGED
|
@@ -273,6 +273,8 @@ interface NodeRedNodes {
|
|
|
273
273
|
}) | undefined;
|
|
274
274
|
createNode(node: NodeRedNode, config: Record<string, any>): void;
|
|
275
275
|
getCredentials(id: string): Record<string, any> | undefined;
|
|
276
|
+
/** Merge credentials into a node's stored credential set (runtime API). */
|
|
277
|
+
addCredentials(id: string, credentials: Record<string, any>): void;
|
|
276
278
|
eachNode(callback: (node: any) => void): void;
|
|
277
279
|
getType(type: string): any;
|
|
278
280
|
getNodeInfo(type: string): any;
|
|
@@ -353,10 +355,17 @@ declare class TypedInput<T = unknown> {
|
|
|
353
355
|
get value(): unknown;
|
|
354
356
|
resolve(msg?: Record<string, any>): Promise<T>;
|
|
355
357
|
}
|
|
356
|
-
interface
|
|
358
|
+
interface JsonSchemaObjectExtensions {
|
|
357
359
|
format?: "node-id" | "flow-id" | "topic-path" | (string & {});
|
|
360
|
+
/** expose this settings property to the editor via RED.settings */
|
|
358
361
|
exportable?: boolean;
|
|
362
|
+
/** set by SchemaType.NodeRef — the referenced config node type */
|
|
359
363
|
"x-nrg-node-type"?: string;
|
|
364
|
+
/** set by SchemaType.TypedInput — marks a TypedInput value/type pair */
|
|
365
|
+
"x-nrg-typed-input"?: boolean;
|
|
366
|
+
/** set by markNonValidatable — ajv skips this property */
|
|
367
|
+
"x-nrg-skip-validation"?: boolean;
|
|
368
|
+
/** form rendering hints consumed by the auto-generated editor form */
|
|
360
369
|
"x-nrg-form"?: {
|
|
361
370
|
icon?: string;
|
|
362
371
|
typedInputTypes?: string[];
|
|
@@ -444,8 +453,8 @@ export interface TNodeRef<T = any> extends TSchema {
|
|
|
444
453
|
format: "node-id";
|
|
445
454
|
"x-nrg-node-type"?: string;
|
|
446
455
|
}
|
|
447
|
-
type
|
|
448
|
-
[K in keyof T]:
|
|
456
|
+
type ResolvedStatic<T> = T extends NodeRefResolved<infer I> ? I : T extends TypedInput<any> ? T : T extends (...args: any[]) => any ? T : T extends Array<infer Item> ? ResolvedStatic<Item>[] : T extends object ? {
|
|
457
|
+
[K in keyof T]: ResolvedStatic<T[K]>;
|
|
449
458
|
} : T;
|
|
450
459
|
/**
|
|
451
460
|
* Infers the TypeScript type from a schema or a record of schemas.
|
|
@@ -456,8 +465,8 @@ type ResolveNodeRefs<T> = T extends NodeRefResolved<infer I> ? I : T extends Typ
|
|
|
456
465
|
* The record form produces a simple mapped type that resolves eagerly,
|
|
457
466
|
* giving `sendToPort()` proper autocomplete in class-based nodes.
|
|
458
467
|
*/
|
|
459
|
-
export type Infer<T extends TSchema | Record<string, TSchema>> = T extends TSchema ?
|
|
460
|
-
[K in keyof T & string]: T[K] extends TSchema ?
|
|
468
|
+
export type Infer<T extends TSchema | Record<string, TSchema>> = T extends TSchema ? ResolvedStatic<Static<T>> : {
|
|
469
|
+
[K in keyof T & string]: T[K] extends TSchema ? ResolvedStatic<Static<T[K]>> : never;
|
|
461
470
|
};
|
|
462
471
|
type TypedInputType = (typeof TYPED_INPUT_TYPES)[number];
|
|
463
472
|
/** Schema type representing a Node-RED TypedInput (value + type pair). */
|
|
@@ -466,7 +475,7 @@ export interface TTypedInput<T = unknown> extends TSchema {
|
|
|
466
475
|
static: TypedInput<T>;
|
|
467
476
|
"x-nrg-typed-input": true;
|
|
468
477
|
}
|
|
469
|
-
interface NrgSchemaOptions extends SchemaOptions,
|
|
478
|
+
interface NrgSchemaOptions extends SchemaOptions, JsonSchemaObjectExtensions {
|
|
470
479
|
}
|
|
471
480
|
/** An NRG object schema created by {@link defineSchema}. */
|
|
472
481
|
export type Schema<T extends TProperties = TProperties> = TObject<T>;
|
|
@@ -482,13 +491,18 @@ type InferOutputs<T> = T extends readonly TSchema[] ? {
|
|
|
482
491
|
} : any;
|
|
483
492
|
declare function NodeRef<T extends new (...args: any[]) => any>(nodeClass: T, options?: NrgSchemaOptions): TNodeRef<InstanceType<T>>;
|
|
484
493
|
declare function TypedInput$1<T = unknown>(options?: NrgSchemaOptions): TTypedInput<T>;
|
|
494
|
+
declare function ReturnProperty(options?: NrgSchemaOptions & {
|
|
495
|
+
default?: string;
|
|
496
|
+
}): import("@sinclair/typebox").TString;
|
|
485
497
|
/**
|
|
486
498
|
* Extended TypeBox type builder with NRG-specific schema types.
|
|
487
|
-
* Includes all standard TypeBox types plus {@link NodeRef}
|
|
499
|
+
* Includes all standard TypeBox types plus {@link NodeRef}, {@link TypedInput}
|
|
500
|
+
* and {@link ReturnProperty}.
|
|
488
501
|
*/
|
|
489
502
|
export declare const SchemaType: import("@sinclair/typebox").JavaScriptTypeBuilder & {
|
|
490
503
|
NodeRef: typeof NodeRef;
|
|
491
504
|
TypedInput: typeof TypedInput$1;
|
|
505
|
+
ReturnProperty: typeof ReturnProperty;
|
|
492
506
|
};
|
|
493
507
|
/**
|
|
494
508
|
* Creates a validated object schema from a set of properties. Automatically
|
|
@@ -522,7 +536,7 @@ export interface NodeConstructor<T = any, TConfig = any, TCredentials = any> {
|
|
|
522
536
|
readonly credentialsSchema?: Schema;
|
|
523
537
|
readonly settingsSchema?: Schema;
|
|
524
538
|
readonly inputSchema?: Schema;
|
|
525
|
-
readonly outputsSchema?:
|
|
539
|
+
readonly outputsSchema?: TSchema | TSchema[] | Record<string, TSchema>;
|
|
526
540
|
readonly validateInput?: boolean;
|
|
527
541
|
readonly validateOutput?: boolean;
|
|
528
542
|
readonly name: string;
|
|
@@ -600,10 +614,32 @@ declare abstract class Node$1<TConfig = any, TCredentials = any, TSettings = any
|
|
|
600
614
|
get credentials(): NodeCredentials<TCredentials> | undefined;
|
|
601
615
|
get settings(): TSettings;
|
|
602
616
|
}
|
|
617
|
+
/**
|
|
618
|
+
* Controls how an outgoing message carries the incoming message's context:
|
|
619
|
+
* - `"nest"` (default): keep all incoming keys and push the full input under
|
|
620
|
+
* `input`, so the prior message — including any value the result overwrites
|
|
621
|
+
* — is always recoverable (`msg.input.output`). The `input` chain
|
|
622
|
+
* accumulates one frame per node, forming a provenance trail visible in the
|
|
623
|
+
* debug panel.
|
|
624
|
+
* - `"carry"`: keep all incoming keys (including any upstream `input`) but do
|
|
625
|
+
* not record this node — context flows through without growing.
|
|
626
|
+
* - `"reset"`: drop all inherited context; the outgoing message is only the
|
|
627
|
+
* result at the return key.
|
|
628
|
+
*/
|
|
629
|
+
export type ContextMode = "nest" | "carry" | "reset";
|
|
603
630
|
/**
|
|
604
631
|
* Base class for nodes that process messages. Provides input/output handling,
|
|
605
632
|
* schema validation, status updates, and emit port management.
|
|
606
633
|
*
|
|
634
|
+
* Every node has a return key (`"output"` by default): the value passed to
|
|
635
|
+
* `send()` is merged into the incoming message at that key and the full prior
|
|
636
|
+
* message is kept under `input` (`{ ...msg, [returnKey]: result, input: msg }`),
|
|
637
|
+
* so upstream properties propagate and the provenance chain is recoverable.
|
|
638
|
+
* Declaring `returnProperty` in the `configSchema` only lets the flow author
|
|
639
|
+
* override the key in the editor — it does not change that a return key always
|
|
640
|
+
* exists. `this.send(x)` always means "x is the result", never "x is the whole
|
|
641
|
+
* message".
|
|
642
|
+
*
|
|
607
643
|
* @example
|
|
608
644
|
* ```ts
|
|
609
645
|
* export default class MyNode extends IONode<Config, any, Input, Output> {
|
|
@@ -612,7 +648,8 @@ declare abstract class Node$1<TConfig = any, TCredentials = any, TSettings = any
|
|
|
612
648
|
* static readonly color = "#ffffff" as const;
|
|
613
649
|
*
|
|
614
650
|
* async input(msg: Input) {
|
|
615
|
-
*
|
|
651
|
+
* // sends { ...msg, output: <result>, input: msg }
|
|
652
|
+
* this.send(msg.output.toUpperCase());
|
|
616
653
|
* }
|
|
617
654
|
* }
|
|
618
655
|
* ```
|
|
@@ -622,7 +659,7 @@ export declare abstract class IONode<TConfig = any, TCredentials = any, TInput =
|
|
|
622
659
|
static readonly align?: "left" | "right";
|
|
623
660
|
static readonly color: HexColor;
|
|
624
661
|
static readonly inputSchema?: Schema;
|
|
625
|
-
static readonly outputsSchema?:
|
|
662
|
+
static readonly outputsSchema?: TSchema | TSchema[] | Record<string, TSchema>;
|
|
626
663
|
static readonly validateInput: boolean;
|
|
627
664
|
static readonly validateOutput: boolean;
|
|
628
665
|
static get inputs(): 0 | 1;
|
|
@@ -632,7 +669,7 @@ export declare abstract class IONode<TConfig = any, TCredentials = any, TInput =
|
|
|
632
669
|
constructor(RED: RED, node: NodeRedNode, config: IONodeConfig<TConfig>, credentials: IONodeCredentials<TCredentials>);
|
|
633
670
|
[WIRE_HANDLERS](nodeRedNode: NodeRedNode, createdPromise: Promise<void>): void;
|
|
634
671
|
input(msg: TInput): void | Promise<void>;
|
|
635
|
-
send(msg: TOutput): void;
|
|
672
|
+
send(msg: TOutput, contextMode?: ContextMode): void;
|
|
636
673
|
get baseOutputs(): number;
|
|
637
674
|
get totalOutputs(): number;
|
|
638
675
|
/**
|
|
@@ -645,7 +682,7 @@ export declare abstract class IONode<TConfig = any, TCredentials = any, TInput =
|
|
|
645
682
|
* throw an error or call `this.error()` for the error port, and the complete
|
|
646
683
|
* port is sent automatically on successful input processing.
|
|
647
684
|
*/
|
|
648
|
-
sendToPort<P extends (TOutput extends Record<string, Record<string, any>> ? keyof TOutput & string : never) | number>(port: P, msg: P extends keyof TOutput ? TOutput[P] : unknown): void;
|
|
685
|
+
sendToPort<P extends (TOutput extends Record<string, Record<string, any>> ? keyof TOutput & string : never) | number>(port: P, msg: P extends keyof TOutput ? TOutput[P] : unknown, contextMode?: ContextMode): void;
|
|
649
686
|
status(status: IONodeStatus): void;
|
|
650
687
|
error(message: string, msg?: any): void;
|
|
651
688
|
updateWires(wires: string[][]): void;
|
|
@@ -660,6 +697,7 @@ type IONodeContextScope = NodeContextScope;
|
|
|
660
697
|
type IONodeConfig<TConfig = any> = NodeConfig<TConfig> & Static<typeof IONodeConfigSchema> & {
|
|
661
698
|
validateInput?: boolean;
|
|
662
699
|
validateOutput?: boolean;
|
|
700
|
+
returnProperty?: string;
|
|
663
701
|
};
|
|
664
702
|
type IONodeCredentials<TCredentials = any> = NodeCredentials<TCredentials>;
|
|
665
703
|
type IONodeStatus = {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type-level contract shared by the server and client planes.
|
|
3
|
+
*
|
|
4
|
+
* `Static<>` of NRG's special schemas (NodeRef, TypedInput) produces these
|
|
5
|
+
* brand shapes. Each plane maps them differently:
|
|
6
|
+
*
|
|
7
|
+
* - server `ResolvedStatic` (server/schemas/types): brand → runtime value
|
|
8
|
+
* (NodeRef → the node instance, TypedInput → the resolving wrapper)
|
|
9
|
+
* - client `EditorStatic` (client/types): brand → editor form value
|
|
10
|
+
* (NodeRef → the referenced node id string, TypedInput → { value, type })
|
|
11
|
+
*
|
|
12
|
+
* Both planes import the brands from here, type-only, so renaming or
|
|
13
|
+
* reshaping a brand is a compile error on both sides instead of silent
|
|
14
|
+
* type drift. Keep this module free of runtime code and imports from
|
|
15
|
+
* either plane.
|
|
16
|
+
*/
|
|
17
|
+
/** Brand produced by `Static` of a NodeRef schema. */
|
|
18
|
+
interface NodeRefResolved<T = any> {
|
|
19
|
+
readonly __nrg_node_ref: true;
|
|
20
|
+
readonly __instance: T;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Structural shape of a resolved TypedInput (the server's TypedInput class
|
|
24
|
+
* instance). The client matches this shape to map the field to its raw
|
|
25
|
+
* editor value pair.
|
|
26
|
+
*/
|
|
27
|
+
interface TypedInputResolved {
|
|
28
|
+
resolve(...args: any[]): any;
|
|
29
|
+
value: unknown;
|
|
30
|
+
type: string;
|
|
31
|
+
}
|
|
32
|
+
export type { NodeRefResolved, TypedInputResolved };
|
|
@@ -29,7 +29,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
29
29
|
default: string;
|
|
30
30
|
};
|
|
31
31
|
}>, {
|
|
32
|
-
|
|
32
|
+
editorInstance: import("vue").ShallowRef<any, any>;
|
|
33
33
|
expandedEditorTray: import("vue").ShallowRef<any, any>;
|
|
34
34
|
}, {
|
|
35
35
|
editorId: string;
|
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
import type { PropType } from "vue";
|
|
2
|
+
import type { JsonPropertySchema } from "../../types";
|
|
3
|
+
type FieldSchema = JsonPropertySchema;
|
|
4
|
+
interface FormField {
|
|
5
|
+
key: string;
|
|
6
|
+
label: string;
|
|
7
|
+
icon: string;
|
|
8
|
+
inputType: "text" | "number" | "boolean" | "select" | "typed" | "config" | "editor" | "array-text";
|
|
9
|
+
required: boolean;
|
|
10
|
+
htmlType?: "text" | "number" | "password";
|
|
11
|
+
options?: Array<{
|
|
12
|
+
value: string;
|
|
13
|
+
label: string;
|
|
14
|
+
}>;
|
|
15
|
+
multiple?: boolean;
|
|
16
|
+
types?: (NodeRED.DefaultTypedInputType | NodeRED.TypedInputTypeDefinition)[];
|
|
17
|
+
configType?: string;
|
|
18
|
+
language?: string;
|
|
19
|
+
toggle?: boolean;
|
|
20
|
+
}
|
|
1
21
|
declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
2
22
|
node: {
|
|
3
23
|
type: PropType<NodeRED.BaseNode>;
|
|
@@ -15,7 +35,6 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
15
35
|
configFields(): FormField[];
|
|
16
36
|
credentialFields(): FormField[];
|
|
17
37
|
}, {
|
|
18
|
-
recalculateOutputs(): void;
|
|
19
38
|
resolveI18n(prefix: string, key: string): string | undefined;
|
|
20
39
|
}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
21
40
|
node: {
|
|
@@ -657,7 +676,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
657
676
|
default: string;
|
|
658
677
|
};
|
|
659
678
|
}>, {
|
|
660
|
-
|
|
679
|
+
editorInstance: import("vue").ShallowRef<any, any>;
|
|
661
680
|
expandedEditorTray: import("vue").ShallowRef<any, any>;
|
|
662
681
|
}, {
|
|
663
682
|
editorId: string;
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import type { Component, App } from "vue";
|
|
2
|
+
import type { TSchema, Static } from "@sinclair/typebox";
|
|
3
|
+
import type { SchemaObject } from "ajv";
|
|
4
|
+
import type { NodeRefResolved, TypedInputResolved } from "../brands";
|
|
5
|
+
import type { JsonSchemaObjectExtensions } from "../schema-options";
|
|
6
|
+
export interface NodeStateCredentials {
|
|
7
|
+
[key: string]: any;
|
|
8
|
+
}
|
|
9
|
+
export interface NodeState {
|
|
10
|
+
credentials: NodeStateCredentials;
|
|
11
|
+
[key: string]: any;
|
|
12
|
+
}
|
|
13
|
+
export interface NodeButtonDefinition {
|
|
14
|
+
toggle: string;
|
|
15
|
+
onClick: () => void;
|
|
16
|
+
enabled?: () => boolean;
|
|
17
|
+
visible?: () => boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface NodeRedNodeButtonDefinition {
|
|
20
|
+
toggle: string;
|
|
21
|
+
onclick: () => void;
|
|
22
|
+
enabled?: () => boolean;
|
|
23
|
+
visible?: () => boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface NodeFormDefinition {
|
|
26
|
+
component?: Component;
|
|
27
|
+
}
|
|
28
|
+
export interface NodeRedNode {
|
|
29
|
+
id: string;
|
|
30
|
+
type: string;
|
|
31
|
+
name: string;
|
|
32
|
+
category: string;
|
|
33
|
+
x: string;
|
|
34
|
+
y: string;
|
|
35
|
+
g: string;
|
|
36
|
+
z: string;
|
|
37
|
+
credentials: Record<string, any>;
|
|
38
|
+
_def: {
|
|
39
|
+
defaults: Record<string, {
|
|
40
|
+
value: string;
|
|
41
|
+
type?: string;
|
|
42
|
+
label?: string;
|
|
43
|
+
required?: boolean;
|
|
44
|
+
}>;
|
|
45
|
+
credentials: Record<string, {
|
|
46
|
+
value: string;
|
|
47
|
+
type?: "password" | "text";
|
|
48
|
+
label?: string;
|
|
49
|
+
required?: boolean;
|
|
50
|
+
}>;
|
|
51
|
+
category: string;
|
|
52
|
+
color?: string;
|
|
53
|
+
icon?: string;
|
|
54
|
+
label?: ((this: NodeRedNode) => string) | string;
|
|
55
|
+
inputs?: number;
|
|
56
|
+
outputs?: number;
|
|
57
|
+
paletteLabel?: ((this: NodeRedNode) => string) | string;
|
|
58
|
+
labelStyle?: ((this: NodeRedNode) => string) | string;
|
|
59
|
+
inputLabels?: ((this: NodeRedNode, index: number) => string) | string;
|
|
60
|
+
outputLabels?: ((this: NodeRedNode, index: number) => string) | string;
|
|
61
|
+
align?: "left" | "right";
|
|
62
|
+
button?: NodeRedNodeButtonDefinition;
|
|
63
|
+
};
|
|
64
|
+
_newState?: NodeRedNode;
|
|
65
|
+
_app?: App | null;
|
|
66
|
+
_: (str: string) => string;
|
|
67
|
+
/** dynamic port count (base outputs + enabled built-in ports) */
|
|
68
|
+
outputs?: number;
|
|
69
|
+
/** injected when the node has an inputSchema */
|
|
70
|
+
validateInput?: boolean;
|
|
71
|
+
/** injected when the node has an outputsSchema */
|
|
72
|
+
validateOutput?: boolean;
|
|
73
|
+
/** present when the node's configSchema declares SchemaType.ReturnProperty() */
|
|
74
|
+
returnProperty?: string;
|
|
75
|
+
/** built-in port toggles, present when declared in the configSchema */
|
|
76
|
+
errorPort?: boolean;
|
|
77
|
+
completePort?: boolean;
|
|
78
|
+
statusPort?: boolean;
|
|
79
|
+
[key: string]: any;
|
|
80
|
+
}
|
|
81
|
+
export interface NodeDefinition {
|
|
82
|
+
type: string;
|
|
83
|
+
category?: string;
|
|
84
|
+
color?: string;
|
|
85
|
+
icon?: ((this: NodeRedNode) => string) | string;
|
|
86
|
+
label?: ((this: NodeRedNode) => string) | string;
|
|
87
|
+
inputs?: number;
|
|
88
|
+
outputs?: number;
|
|
89
|
+
paletteLabel?: ((this: NodeRedNode) => string) | string;
|
|
90
|
+
labelStyle?: ((this: NodeRedNode) => string) | string;
|
|
91
|
+
inputLabels?: ((this: NodeRedNode, index: number) => string) | string;
|
|
92
|
+
outputLabels?: ((this: NodeRedNode, index: number) => string) | string;
|
|
93
|
+
align?: "left" | "right";
|
|
94
|
+
button?: NodeButtonDefinition;
|
|
95
|
+
onEditResize?: (this: NodeRedNode, size: {
|
|
96
|
+
width: number;
|
|
97
|
+
height: number;
|
|
98
|
+
}) => void;
|
|
99
|
+
onPaletteAdd?: (this: NodeRedNode) => void;
|
|
100
|
+
onPaletteRemove?: (this: NodeRedNode) => void;
|
|
101
|
+
form?: NodeFormDefinition;
|
|
102
|
+
}
|
|
103
|
+
/** Form rendering hints carried by the `x-nrg-form` schema keyword. */
|
|
104
|
+
export type NrgFormOptions = NonNullable<JsonSchemaObjectExtensions["x-nrg-form"]>;
|
|
105
|
+
/**
|
|
106
|
+
* A serialized property schema inside {@link JsonSchemaObject} `properties`,
|
|
107
|
+
* including NRG's custom keywords (shared vocabulary in core/schema-options)
|
|
108
|
+
* that drive form rendering and NodeRef/TypedInput identification.
|
|
109
|
+
*/
|
|
110
|
+
export interface JsonPropertySchema extends JsonSchemaObjectExtensions {
|
|
111
|
+
type?: string | string[];
|
|
112
|
+
properties?: Record<string, JsonPropertySchema>;
|
|
113
|
+
required?: string[];
|
|
114
|
+
enum?: unknown[];
|
|
115
|
+
anyOf?: JsonPropertySchema[];
|
|
116
|
+
const?: unknown;
|
|
117
|
+
items?: JsonPropertySchema;
|
|
118
|
+
title?: string;
|
|
119
|
+
description?: string;
|
|
120
|
+
default?: unknown;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* A serialized JSON Schema object as the build pipeline emits it (never a
|
|
124
|
+
* live TypeBox instance). Extends ajv's `SchemaObject` so it flows into
|
|
125
|
+
* validator APIs without casts, while keeping the `type: "object"`
|
|
126
|
+
* discriminant and structured `properties`/`required` that ajv's open
|
|
127
|
+
* `[x: string]: any` shape does not provide.
|
|
128
|
+
*/
|
|
129
|
+
export interface JsonSchemaObject extends SchemaObject {
|
|
130
|
+
type: "object";
|
|
131
|
+
properties?: Record<string, JsonPropertySchema>;
|
|
132
|
+
required?: string[];
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* A node definition as it exists at editor runtime, after the build pipeline
|
|
136
|
+
* merged in the schema-derived artifacts (defaults, credentials, serialized
|
|
137
|
+
* schemas). Authors write {@link NodeDefinition}; the inliner provides the
|
|
138
|
+
* rest.
|
|
139
|
+
*/
|
|
140
|
+
export interface RuntimeNodeDefinition extends NodeDefinition {
|
|
141
|
+
defaults?: NodeDefaults;
|
|
142
|
+
credentials?: NodeCredentials;
|
|
143
|
+
configSchema?: JsonSchemaObject;
|
|
144
|
+
credentialsSchema?: JsonSchemaObject;
|
|
145
|
+
inputSchema?: JsonSchemaObject;
|
|
146
|
+
/**
|
|
147
|
+
* Single port, positional ports, or named ports (key = port name).
|
|
148
|
+
* Not constrained to object schemas: with returnProperty the raw sent
|
|
149
|
+
* value is validated, so results may be any schema shape.
|
|
150
|
+
*/
|
|
151
|
+
outputsSchema?: JsonPropertySchema | JsonPropertySchema[] | Record<string, JsonPropertySchema>;
|
|
152
|
+
}
|
|
153
|
+
export interface NodeDefaults {
|
|
154
|
+
[key: string]: {
|
|
155
|
+
value: any;
|
|
156
|
+
type?: string;
|
|
157
|
+
label?: string;
|
|
158
|
+
required?: boolean;
|
|
159
|
+
validate?: (this: NodeRedNode, value: any, opt: any) => any;
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
export interface NodeCredentials {
|
|
163
|
+
[key: string]: {
|
|
164
|
+
value?: string;
|
|
165
|
+
type?: "password" | "text";
|
|
166
|
+
label?: string;
|
|
167
|
+
required?: boolean;
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
export interface NodeFeatures {
|
|
171
|
+
hasInputSchema: boolean;
|
|
172
|
+
hasOutputSchema: boolean;
|
|
173
|
+
}
|
|
174
|
+
/** Client-side representation of a TypedInput field: the raw value string and its type selector. */
|
|
175
|
+
export interface TypedInputValue {
|
|
176
|
+
value: string;
|
|
177
|
+
type: string;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Maps a schema's static type to the raw values the editor form holds.
|
|
181
|
+
* The server counterpart (`ResolvedStatic` in server/schemas/types) maps the
|
|
182
|
+
* same brands — shared via core/brands — to resolved runtime values instead.
|
|
183
|
+
* - `NodeRef<T>` → `string` (the referenced node's id)
|
|
184
|
+
* - `TypedInput<T>` → `TypedInputValue` (raw value + type pair)
|
|
185
|
+
* - Functions pass through, arrays and objects map recursively
|
|
186
|
+
*/
|
|
187
|
+
export type EditorStatic<T> = T extends NodeRefResolved<any> ? string : T extends TypedInputResolved ? TypedInputValue : T extends (...args: any[]) => any ? T : T extends Array<infer I> ? EditorStatic<I>[] : T extends object ? {
|
|
188
|
+
[K in keyof T]: EditorStatic<T[K]>;
|
|
189
|
+
} : T;
|
|
190
|
+
/**
|
|
191
|
+
* Infers the client-side TypeScript type from a TypeBox schema.
|
|
192
|
+
*
|
|
193
|
+
* Resolves schema types to their client form representations:
|
|
194
|
+
* - `NodeRef<T>` → `string` (node ID in the editor)
|
|
195
|
+
* - `TypedInput<T>` → `{ value: string; type: string }`
|
|
196
|
+
* - All other types resolve via TypeBox's `Static<T>`
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```ts
|
|
200
|
+
* import type { Infer } from "@bonsae/nrg/client";
|
|
201
|
+
* import type { ConfigSchema } from "../schemas/my-node";
|
|
202
|
+
*
|
|
203
|
+
* type Config = Infer<typeof ConfigSchema>;
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
export type Infer<T extends TSchema> = EditorStatic<Static<T>>;
|
|
@@ -11,13 +11,13 @@ declare module "vue" {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export interface GlobalComponents {
|
|
14
|
-
NodeRedConfigInput: (typeof import("./form/components/node-red-config-input.vue"))["default"];
|
|
15
|
-
NodeRedEditorInput: (typeof import("./form/components/node-red-editor-input.vue"))["default"];
|
|
16
|
-
NodeRedInputLabel: (typeof import("./form/components/node-red-input-label.vue"))["default"];
|
|
17
|
-
NodeRedInput: (typeof import("./form/components/node-red-input.vue"))["default"];
|
|
18
|
-
NodeRedJsonSchemaForm: (typeof import("./form/components/node-red-json-schema-form.vue"))["default"];
|
|
19
|
-
NodeRedSelectInput: (typeof import("./form/components/node-red-select-input.vue"))["default"];
|
|
20
|
-
NodeRedToggle: (typeof import("./form/components/node-red-toggle.vue"))["default"];
|
|
21
|
-
NodeRedTypedInput: (typeof import("./form/components/node-red-typed-input.vue"))["default"];
|
|
14
|
+
NodeRedConfigInput: (typeof import("./client/form/components/node-red-config-input.vue"))["default"];
|
|
15
|
+
NodeRedEditorInput: (typeof import("./client/form/components/node-red-editor-input.vue"))["default"];
|
|
16
|
+
NodeRedInputLabel: (typeof import("./client/form/components/node-red-input-label.vue"))["default"];
|
|
17
|
+
NodeRedInput: (typeof import("./client/form/components/node-red-input.vue"))["default"];
|
|
18
|
+
NodeRedJsonSchemaForm: (typeof import("./client/form/components/node-red-json-schema-form.vue"))["default"];
|
|
19
|
+
NodeRedSelectInput: (typeof import("./client/form/components/node-red-select-input.vue"))["default"];
|
|
20
|
+
NodeRedToggle: (typeof import("./client/form/components/node-red-toggle.vue"))["default"];
|
|
21
|
+
NodeRedTypedInput: (typeof import("./client/form/components/node-red-typed-input.vue"))["default"];
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
declare const TYPED_INPUT_TYPES: readonly ["msg", "flow", "global", "str", "num", "bool", "json", "bin", "re", "jsonata", "date", "env", "node", "cred"];
|
|
2
|
+
/** Reserved config property names for built-in ports (error, complete, status) */
|
|
3
|
+
declare const BUILTIN_PORT_KEYS: readonly ["errorPort", "completePort", "statusPort"];
|
|
4
|
+
export { BUILTIN_PORT_KEYS, TYPED_INPUT_TYPES };
|