@bonsae/nrg 0.7.0 → 0.8.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 +1 -1
- package/server/index.cjs +66 -37
- package/types/server.d.ts +45 -32
package/package.json
CHANGED
package/server/index.cjs
CHANGED
|
@@ -236,6 +236,48 @@ var NrgError = class _NrgError extends Error {
|
|
|
236
236
|
}
|
|
237
237
|
};
|
|
238
238
|
|
|
239
|
+
// src/core/server/typed-input.ts
|
|
240
|
+
var TypedInput = class {
|
|
241
|
+
constructor(RED, node, input) {
|
|
242
|
+
this.RED = RED;
|
|
243
|
+
this.node = node;
|
|
244
|
+
this.input = input;
|
|
245
|
+
}
|
|
246
|
+
resolvers = {
|
|
247
|
+
// evaluateNodeProperty returns the node ID string for "node" type —
|
|
248
|
+
// resolve it to the actual node instance via RED.nodes.getNode,
|
|
249
|
+
// then surface the NRG wrapper if available.
|
|
250
|
+
node: (raw) => {
|
|
251
|
+
if (typeof raw === "string") {
|
|
252
|
+
const node = this.RED.nodes.getNode(raw);
|
|
253
|
+
return node?._node ?? node ?? raw;
|
|
254
|
+
}
|
|
255
|
+
return raw?._node ?? raw;
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
get type() {
|
|
259
|
+
return this.input.type;
|
|
260
|
+
}
|
|
261
|
+
get value() {
|
|
262
|
+
return this.input.value;
|
|
263
|
+
}
|
|
264
|
+
resolve(msg) {
|
|
265
|
+
return new Promise((resolve, reject) => {
|
|
266
|
+
this.RED.util.evaluateNodeProperty(
|
|
267
|
+
this.input.value,
|
|
268
|
+
this.input.type,
|
|
269
|
+
this.node,
|
|
270
|
+
msg,
|
|
271
|
+
(err, raw) => {
|
|
272
|
+
if (err) return reject(err);
|
|
273
|
+
const post = this.resolvers[this.input.type];
|
|
274
|
+
resolve(post ? post(raw) : raw);
|
|
275
|
+
}
|
|
276
|
+
);
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
|
|
239
281
|
// src/core/server/nodes/utils.ts
|
|
240
282
|
function setupContext(context, store) {
|
|
241
283
|
return {
|
|
@@ -259,14 +301,16 @@ function setupContext(context, store) {
|
|
|
259
301
|
)
|
|
260
302
|
};
|
|
261
303
|
}
|
|
262
|
-
function setupConfigProxy(
|
|
304
|
+
function setupConfigProxy(opts) {
|
|
305
|
+
const { RED, node, config, schema } = opts;
|
|
263
306
|
const SKIP_PROPS = /* @__PURE__ */ new Set(["id", "_id", "_users"]);
|
|
264
307
|
const nodeRefProps = /* @__PURE__ */ new Set();
|
|
308
|
+
const typedInputProps = /* @__PURE__ */ new Set();
|
|
265
309
|
if (schema?.properties) {
|
|
266
310
|
for (const [key, propSchema] of Object.entries(schema.properties)) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
311
|
+
const s = propSchema;
|
|
312
|
+
if (s?.["x-nrg-node-type"]) nodeRefProps.add(key);
|
|
313
|
+
if (s?.["x-nrg-typed-input"]) typedInputProps.add(key);
|
|
270
314
|
}
|
|
271
315
|
}
|
|
272
316
|
const cache = /* @__PURE__ */ new WeakMap();
|
|
@@ -274,12 +318,9 @@ function setupConfigProxy(RED, config, schema) {
|
|
|
274
318
|
const cached = cache.get(obj);
|
|
275
319
|
if (cached) return cached;
|
|
276
320
|
if (Array.isArray(obj)) {
|
|
277
|
-
const mapped = obj.map(
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
}
|
|
281
|
-
return item;
|
|
282
|
-
});
|
|
321
|
+
const mapped = obj.map(
|
|
322
|
+
(item) => item && typeof item === "object" ? createProxy(item) : item
|
|
323
|
+
);
|
|
283
324
|
cache.set(obj, mapped);
|
|
284
325
|
return mapped;
|
|
285
326
|
}
|
|
@@ -291,6 +332,14 @@ function setupConfigProxy(RED, config, schema) {
|
|
|
291
332
|
if (typeof value === "string" && value.length > 0 && nodeRefProps.has(prop)) {
|
|
292
333
|
return RED.nodes.getNode(value)?._node ?? value;
|
|
293
334
|
}
|
|
335
|
+
if (typedInputProps.has(prop) && value && typeof value === "object" && "type" in value && "value" in value) {
|
|
336
|
+
let ref = cache.get(value);
|
|
337
|
+
if (!ref) {
|
|
338
|
+
ref = new TypedInput(RED, node, value);
|
|
339
|
+
cache.set(value, ref);
|
|
340
|
+
}
|
|
341
|
+
return ref;
|
|
342
|
+
}
|
|
294
343
|
if (value && typeof value === "object") {
|
|
295
344
|
return createProxy(value);
|
|
296
345
|
}
|
|
@@ -385,11 +434,12 @@ var Node = class {
|
|
|
385
434
|
);
|
|
386
435
|
}
|
|
387
436
|
}
|
|
388
|
-
this.config = setupConfigProxy(
|
|
437
|
+
this.config = setupConfigProxy({
|
|
389
438
|
RED,
|
|
439
|
+
node,
|
|
390
440
|
config,
|
|
391
|
-
constructor.configSchema
|
|
392
|
-
);
|
|
441
|
+
schema: constructor.configSchema
|
|
442
|
+
});
|
|
393
443
|
if (constructor.credentialsSchema && credentials) {
|
|
394
444
|
this.log("Validating credentials");
|
|
395
445
|
const credResult = validator.validate(
|
|
@@ -432,28 +482,6 @@ var Node = class {
|
|
|
432
482
|
clearInterval(interval);
|
|
433
483
|
this.intervals.delete(interval);
|
|
434
484
|
}
|
|
435
|
-
// NOTE: typing msg isnt necessary in this case
|
|
436
|
-
resolveTypedInput(typedInput, msg) {
|
|
437
|
-
return new Promise((resolve, reject) => {
|
|
438
|
-
this.RED.util.evaluateNodeProperty(
|
|
439
|
-
typedInput.value,
|
|
440
|
-
typedInput.type,
|
|
441
|
-
this.node,
|
|
442
|
-
msg,
|
|
443
|
-
(error, result) => {
|
|
444
|
-
if (error) {
|
|
445
|
-
reject(error);
|
|
446
|
-
return;
|
|
447
|
-
}
|
|
448
|
-
if (typedInput.type === "node" && result) {
|
|
449
|
-
resolve(result._node ?? result);
|
|
450
|
-
return;
|
|
451
|
-
}
|
|
452
|
-
resolve(result);
|
|
453
|
-
}
|
|
454
|
-
);
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
485
|
// NOTE: used by the registered function. Had to be a different one to avoid calling the parent's closed again
|
|
458
486
|
/** @internal */
|
|
459
487
|
async _closed(removed) {
|
|
@@ -795,16 +823,17 @@ function NodeRef(nodeClass, options) {
|
|
|
795
823
|
[import_typebox.Kind]: "NodeRef"
|
|
796
824
|
};
|
|
797
825
|
}
|
|
798
|
-
function
|
|
826
|
+
function TypedInput2(options) {
|
|
799
827
|
return {
|
|
800
828
|
...TypedInputSchema,
|
|
829
|
+
"x-nrg-typed-input": true,
|
|
801
830
|
...options,
|
|
802
831
|
[import_typebox.Kind]: "TypedInput"
|
|
803
832
|
};
|
|
804
833
|
}
|
|
805
834
|
var SchemaType = Object.assign({}, import_typebox.Type, {
|
|
806
835
|
NodeRef,
|
|
807
|
-
TypedInput
|
|
836
|
+
TypedInput: TypedInput2
|
|
808
837
|
});
|
|
809
838
|
function markNonValidatable(schema) {
|
|
810
839
|
const type = schema.type;
|
package/types/server.d.ts
CHANGED
|
@@ -1716,33 +1716,6 @@ declare const TYPED_INPUT_TYPES: readonly [
|
|
|
1716
1716
|
"node",
|
|
1717
1717
|
"cred"
|
|
1718
1718
|
];
|
|
1719
|
-
export interface TNodeRef<T = any> extends TSchema {
|
|
1720
|
-
[Kind]: "NodeRef";
|
|
1721
|
-
static: T;
|
|
1722
|
-
type: "string";
|
|
1723
|
-
"x-nrg-node-type"?: string;
|
|
1724
|
-
}
|
|
1725
|
-
export type ResolveNodeRefs<T> = T extends TNodeRef<infer N> ? N : T extends (...args: any[]) => any ? T : T extends Array<infer Item> ? ResolveNodeRefs<Item>[] : T extends object ? {
|
|
1726
|
-
[K in keyof T]: ResolveNodeRefs<T[K]>;
|
|
1727
|
-
} : T;
|
|
1728
|
-
export type Infer<T extends TSchema> = ResolveNodeRefs<Static<T>>;
|
|
1729
|
-
export type TypedInputType = (typeof TYPED_INPUT_TYPES)[number];
|
|
1730
|
-
export interface TTypedInput extends TSchema {
|
|
1731
|
-
[Kind]: "TypedInput";
|
|
1732
|
-
static: {
|
|
1733
|
-
value: string | number | boolean | null;
|
|
1734
|
-
type: TypedInputType;
|
|
1735
|
-
};
|
|
1736
|
-
}
|
|
1737
|
-
export interface NrgFormOptions {
|
|
1738
|
-
icon?: string;
|
|
1739
|
-
typedInputTypes?: string[];
|
|
1740
|
-
editorLanguage?: string;
|
|
1741
|
-
toggle?: boolean;
|
|
1742
|
-
}
|
|
1743
|
-
export interface Schema<T extends TProperties = TProperties> extends TObject<T> {
|
|
1744
|
-
$id: string;
|
|
1745
|
-
}
|
|
1746
1719
|
export interface NodeRedRuntimeSettings {
|
|
1747
1720
|
userDir?: string;
|
|
1748
1721
|
nodesDir?: string | string[];
|
|
@@ -2072,6 +2045,48 @@ export interface NodeRedContextStore {
|
|
|
2072
2045
|
set(key: string, value: any, store: string | undefined, callback: (err: Error | null) => void): void;
|
|
2073
2046
|
keys(store: string | undefined, callback: (err: Error | null, keys: string[]) => void): void;
|
|
2074
2047
|
}
|
|
2048
|
+
declare class TypedInput<T = unknown> {
|
|
2049
|
+
private readonly RED;
|
|
2050
|
+
private readonly node;
|
|
2051
|
+
private readonly input;
|
|
2052
|
+
private readonly resolvers;
|
|
2053
|
+
constructor(RED: RED, node: NodeRedNode, input: {
|
|
2054
|
+
value: unknown;
|
|
2055
|
+
type: TypedInputType;
|
|
2056
|
+
});
|
|
2057
|
+
get type(): TypedInputType;
|
|
2058
|
+
get value(): unknown;
|
|
2059
|
+
resolve(msg?: Record<string, any>): Promise<T>;
|
|
2060
|
+
}
|
|
2061
|
+
export interface TNodeRef<T = any> extends TSchema {
|
|
2062
|
+
[Kind]: "NodeRef";
|
|
2063
|
+
static: T;
|
|
2064
|
+
type: "string";
|
|
2065
|
+
"x-nrg-node-type"?: string;
|
|
2066
|
+
}
|
|
2067
|
+
export type ResolveNodeRefs<T> = T extends TypedInput<any> ? T : T extends (...args: any[]) => any ? T : T extends Array<infer Item> ? ResolveNodeRefs<Item>[] : T extends object ? {
|
|
2068
|
+
[K in keyof T]: ResolveNodeRefs<T[K]>;
|
|
2069
|
+
} : T;
|
|
2070
|
+
export type Infer<T extends TSchema> = ResolveNodeRefs<Static<T>>;
|
|
2071
|
+
export type TypedInputType = (typeof TYPED_INPUT_TYPES)[number];
|
|
2072
|
+
export interface TTypedInput<T = unknown> extends TSchema {
|
|
2073
|
+
[Kind]: "TypedInput";
|
|
2074
|
+
static: TypedInput<T>;
|
|
2075
|
+
}
|
|
2076
|
+
export interface NrgFormOptions {
|
|
2077
|
+
icon?: string;
|
|
2078
|
+
typedInputTypes?: string[];
|
|
2079
|
+
editorLanguage?: string;
|
|
2080
|
+
toggle?: boolean;
|
|
2081
|
+
}
|
|
2082
|
+
export interface NrgSchemaOptions extends SchemaOptions {
|
|
2083
|
+
exportable?: boolean;
|
|
2084
|
+
"x-nrg-node-type"?: string;
|
|
2085
|
+
"x-nrg-form"?: NrgFormOptions;
|
|
2086
|
+
}
|
|
2087
|
+
export interface Schema<T extends TProperties = TProperties> extends TObject<T> {
|
|
2088
|
+
$id: string;
|
|
2089
|
+
}
|
|
2075
2090
|
declare const NodeConfigSchema: TObject<{
|
|
2076
2091
|
id: TString;
|
|
2077
2092
|
type: TString;
|
|
@@ -2095,11 +2110,11 @@ declare const IONodeConfigSchema: TObject<{
|
|
|
2095
2110
|
name: TString;
|
|
2096
2111
|
z: TOptional<TString>;
|
|
2097
2112
|
}>;
|
|
2098
|
-
declare function NodeRef<T extends new (...args: any[]) => any>(nodeClass: T, options?:
|
|
2099
|
-
declare function TypedInput(options?:
|
|
2113
|
+
declare function NodeRef<T extends new (...args: any[]) => any>(nodeClass: T, options?: NrgSchemaOptions): TNodeRef<InstanceType<T>>;
|
|
2114
|
+
declare function TypedInput$1<T = unknown>(options?: NrgSchemaOptions): TTypedInput<T>;
|
|
2100
2115
|
export declare const SchemaType: JavaScriptTypeBuilder & {
|
|
2101
2116
|
NodeRef: typeof NodeRef;
|
|
2102
|
-
TypedInput: typeof TypedInput;
|
|
2117
|
+
TypedInput: typeof TypedInput$1;
|
|
2103
2118
|
};
|
|
2104
2119
|
export declare function defineSchema<T extends TProperties>(properties: T, options: ObjectOptions & {
|
|
2105
2120
|
$id: string;
|
|
@@ -2112,7 +2127,6 @@ export interface NodeContextStore {
|
|
|
2112
2127
|
}
|
|
2113
2128
|
export type NodeConfig<TConfig = any> = TConfig & Static<typeof NodeConfigSchema>;
|
|
2114
2129
|
export type NodeCredentials<TCredentials = any> = TCredentials;
|
|
2115
|
-
type TypedInput$1 = Static<TTypedInput>;
|
|
2116
2130
|
export type IONodeContextScope = NodeContextScope;
|
|
2117
2131
|
export type IONodeConfig<TConfig = any> = NodeConfig<TConfig> & Static<typeof IONodeConfigSchema> & {
|
|
2118
2132
|
validateInput?: boolean;
|
|
@@ -2257,7 +2271,6 @@ declare abstract class Node$1<TConfig = any, TCredentials = any, TSettings = any
|
|
|
2257
2271
|
clearInterval(interval: NodeJS.Timeout): void;
|
|
2258
2272
|
created?(): void | Promise<void>;
|
|
2259
2273
|
closed?(removed?: boolean): void | Promise<void>;
|
|
2260
|
-
resolveTypedInput<T = any>(typedInput: TypedInput$1, msg?: Record<string, any>): Promise<T>;
|
|
2261
2274
|
on(event: string, callback: (...args: any[]) => void): void;
|
|
2262
2275
|
log(msg: any): void;
|
|
2263
2276
|
warn(message: string): void;
|