@bonsae/nrg 0.21.1 → 0.22.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.
Files changed (40) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2 -3
  3. package/package.json +14 -9
  4. package/schemas/labels.schema.json +15 -5
  5. package/server/index.cjs +2 -1346
  6. package/test/client/component/index.js +41 -224
  7. package/test/client/component/setup.js +201 -1475
  8. package/test/client/e2e/config.js +12 -0
  9. package/test/client/e2e/index.js +422 -199
  10. package/test/client/unit/index.js +19 -32
  11. package/test/client/unit/setup.js +28 -21
  12. package/test/server/integration/index.js +2 -26
  13. package/test/server/unit/index.js +2 -184
  14. package/types/client.d.ts +1 -259
  15. package/types/server.d.ts +1 -892
  16. package/types/test-client-component.d.ts +7 -143
  17. package/types/test-client-e2e.d.ts +0 -6
  18. package/types/test-client-unit.d.ts +11 -105
  19. package/types/test-server-integration.d.ts +73 -49
  20. package/types/test-server-unit.d.ts +26 -2
  21. package/types/vite.d.ts +2 -0
  22. package/vite/index.js +381 -150
  23. package/server/resources/nrg-client.js +0 -7495
  24. package/test/client/component/nrg.css +0 -1
  25. package/types/shims/brands.d.ts +0 -32
  26. package/types/shims/client/form/components/node-red-config-input.vue.d.ts +0 -125
  27. package/types/shims/client/form/components/node-red-editor-input.vue.d.ts +0 -124
  28. package/types/shims/client/form/components/node-red-input-label.vue.d.ts +0 -34
  29. package/types/shims/client/form/components/node-red-input.vue.d.ts +0 -123
  30. package/types/shims/client/form/components/node-red-json-schema-form.vue.d.ts +0 -772
  31. package/types/shims/client/form/components/node-red-select-input.vue.d.ts +0 -132
  32. package/types/shims/client/form/components/node-red-toggle.vue.d.ts +0 -36
  33. package/types/shims/client/form/components/node-red-typed-input.vue.d.ts +0 -151
  34. package/types/shims/client/globals.d.ts +0 -320
  35. package/types/shims/client/types.d.ts +0 -220
  36. package/types/shims/components.d.ts +0 -23
  37. package/types/shims/constants.d.ts +0 -4
  38. package/types/shims/schema-options.d.ts +0 -24
  39. package/types/shims/shims-vue.d.ts +0 -5
  40. package/types/shims/typebox.d.ts +0 -10
@@ -1,4 +1,4 @@
1
- // src/test/client/mocks.ts
1
+ // src/test/client/mocks/red.ts
2
2
  function createSettings() {
3
3
  const settings = {
4
4
  get(key) {
@@ -213,17 +213,19 @@ function createRED() {
213
213
  });
214
214
  return red;
215
215
  }
216
- function ensureState(el) {
216
+
217
+ // src/test/client/mocks/jquery.ts
218
+ function emptyState() {
219
+ return { typedInput: { value: "", type: "" }, listeners: {} };
220
+ }
221
+ function ensureJQueryState(el) {
217
222
  if (el && !el.__jqState) {
218
- el.__jqState = {
219
- typedInput: { value: "", type: "" },
220
- listeners: {}
221
- };
223
+ el.__jqState = emptyState();
222
224
  }
223
- return el ? el.__jqState : { typedInput: { value: "", type: "" }, listeners: {} };
225
+ return el ? el.__jqState : emptyState();
224
226
  }
225
- function createJQ(el) {
226
- const state = ensureState(el);
227
+ function createJQueryElement(el) {
228
+ const state = ensureJQueryState(el);
227
229
  const jq = {
228
230
  0: el,
229
231
  length: el ? 1 : 0,
@@ -311,7 +313,7 @@ function createJQ(el) {
311
313
  return "";
312
314
  },
313
315
  find(selector) {
314
- return createJQ(el?.querySelector(selector) ?? null);
316
+ return createJQueryElement(el?.querySelector(selector) ?? null);
315
317
  },
316
318
  append(child) {
317
319
  const childEl = child?.[0] || child;
@@ -364,34 +366,19 @@ function createJQuery() {
364
366
  }
365
367
  }
366
368
  }
367
- return createJQ(el);
369
+ return createJQueryElement(el);
368
370
  }
369
- return createJQ(document.querySelector(selector));
371
+ return createJQueryElement(document.querySelector(selector));
370
372
  }
371
- if (selector instanceof Element) return createJQ(selector);
373
+ if (selector instanceof Element) return createJQueryElement(selector);
372
374
  if (selector && typeof selector === "object" && selector.nodeType)
373
- return createJQ(selector);
374
- return createJQ(null);
375
+ return createJQueryElement(selector);
376
+ return createJQueryElement(null);
375
377
  };
376
378
  }
377
379
 
378
- // src/core/client/use-form-node.ts
379
- import { inject } from "vue";
380
- function useFormNode() {
381
- const node = inject("__nrg_form_node");
382
- const schema = inject("__nrg_form_schema");
383
- const errors = inject("__nrg_form_errors");
384
- if (!node) {
385
- throw new Error(
386
- "useFormNode() must be called inside a form component mounted by NRG."
387
- );
388
- }
389
- return {
390
- node,
391
- schema,
392
- errors
393
- };
394
- }
380
+ // src/test/client/unit/index.ts
381
+ import { useFormNode } from "@bonsae/nrg-runtime/internal/client";
395
382
  export {
396
383
  createJQuery,
397
384
  createRED,
@@ -1,7 +1,7 @@
1
- // src/test/client/unit/setup.ts
1
+ // src/test/client/install-mocks.ts
2
2
  import { beforeEach } from "vitest";
3
3
 
4
- // src/test/client/mocks.ts
4
+ // src/test/client/mocks/red.ts
5
5
  function createSettings() {
6
6
  const settings = {
7
7
  get(key) {
@@ -219,17 +219,19 @@ function createRED() {
219
219
  });
220
220
  return red;
221
221
  }
222
- function ensureState(el) {
222
+
223
+ // src/test/client/mocks/jquery.ts
224
+ function emptyState() {
225
+ return { typedInput: { value: "", type: "" }, listeners: {} };
226
+ }
227
+ function ensureJQueryState(el) {
223
228
  if (el && !el.__jqState) {
224
- el.__jqState = {
225
- typedInput: { value: "", type: "" },
226
- listeners: {}
227
- };
229
+ el.__jqState = emptyState();
228
230
  }
229
- return el ? el.__jqState : { typedInput: { value: "", type: "" }, listeners: {} };
231
+ return el ? el.__jqState : emptyState();
230
232
  }
231
- function createJQ(el) {
232
- const state = ensureState(el);
233
+ function createJQueryElement(el) {
234
+ const state = ensureJQueryState(el);
233
235
  const jq = {
234
236
  0: el,
235
237
  length: el ? 1 : 0,
@@ -317,7 +319,7 @@ function createJQ(el) {
317
319
  return "";
318
320
  },
319
321
  find(selector) {
320
- return createJQ(el?.querySelector(selector) ?? null);
322
+ return createJQueryElement(el?.querySelector(selector) ?? null);
321
323
  },
322
324
  append(child) {
323
325
  const childEl = child?.[0] || child;
@@ -370,20 +372,25 @@ function createJQuery() {
370
372
  }
371
373
  }
372
374
  }
373
- return createJQ(el);
375
+ return createJQueryElement(el);
374
376
  }
375
- return createJQ(document.querySelector(selector));
377
+ return createJQueryElement(document.querySelector(selector));
376
378
  }
377
- if (selector instanceof Element) return createJQ(selector);
379
+ if (selector instanceof Element) return createJQueryElement(selector);
378
380
  if (selector && typeof selector === "object" && selector.nodeType)
379
- return createJQ(selector);
380
- return createJQ(null);
381
+ return createJQueryElement(selector);
382
+ return createJQueryElement(null);
381
383
  };
382
384
  }
383
385
 
386
+ // src/test/client/install-mocks.ts
387
+ function installEditorMocks() {
388
+ window.$ = createJQuery();
389
+ window.RED = createRED();
390
+ beforeEach(() => {
391
+ resetRED(window.RED);
392
+ });
393
+ }
394
+
384
395
  // src/test/client/unit/setup.ts
385
- window.$ = createJQuery();
386
- window.RED = createRED();
387
- beforeEach(() => {
388
- resetRED(window.RED);
389
- });
396
+ installEditorMocks();
@@ -4,7 +4,7 @@ import os from "os";
4
4
  import fs from "fs";
5
5
  import path from "path";
6
6
  import { createRequire } from "module";
7
- import { registerTypes } from "@bonsae/nrg/server";
7
+ import { registerTypes } from "@bonsae/nrg-runtime/server";
8
8
 
9
9
  // src/test/server/integration/recorder.ts
10
10
  var Recorder = class {
@@ -78,32 +78,8 @@ var Recorder = class {
78
78
  }
79
79
  };
80
80
 
81
- // src/core/server/nodes/utils.ts
82
- import { Kind } from "@sinclair/typebox";
83
- function setupContext(context, store) {
84
- return {
85
- get: (key) => new Promise(
86
- (resolve, reject) => context.get(
87
- key,
88
- store,
89
- (error, value) => error ? reject(error) : resolve(value)
90
- )
91
- ),
92
- set: (key, value) => new Promise(
93
- (resolve, reject) => context.set(
94
- key,
95
- value,
96
- store,
97
- (error) => error ? reject(error) : resolve()
98
- )
99
- ),
100
- keys: () => new Promise(
101
- (resolve, reject) => context.keys(store, (error, k) => error ? reject(error) : resolve(k))
102
- )
103
- };
104
- }
105
-
106
81
  // src/test/server/integration/flow.ts
82
+ import { setupContext } from "@bonsae/nrg-runtime/internal/server";
107
83
  var seq = 0;
108
84
  function genId(prefix) {
109
85
  seq += 1;
@@ -235,191 +235,9 @@ function createNodeRedNode(options = {}) {
235
235
  };
236
236
  }
237
237
 
238
- // src/core/validator.ts
239
- import Ajv from "ajv";
240
- import addFormats from "ajv-formats";
241
- import addErrors from "ajv-errors";
242
- var Validator = class {
243
- ajv;
244
- constructor(options) {
245
- const { customKeywords, customFormats, ...ajvOptions } = options || {};
246
- this.ajv = new Ajv({
247
- allErrors: true,
248
- code: {
249
- source: false
250
- },
251
- coerceTypes: true,
252
- removeAdditional: false,
253
- strict: false,
254
- strictSchema: false,
255
- useDefaults: true,
256
- validateFormats: true,
257
- // NOTE: typebox handles validation via typescript
258
- // NOTE: if true, types that are not serializable JSON, like Function, would not work
259
- validateSchema: false,
260
- verbose: true,
261
- ...ajvOptions
262
- });
263
- addFormats(this.ajv);
264
- addErrors(this.ajv);
265
- this.addCustomKeywords(customKeywords || []);
266
- this.addCustomFormats(customFormats || {});
267
- }
268
- /**
269
- * Add custom keywords to the validator
270
- */
271
- addCustomKeywords(keywords) {
272
- if (!keywords) return;
273
- keywords.forEach((keyword) => {
274
- this.ajv.addKeyword(keyword);
275
- });
276
- }
277
- /**
278
- * Add custom formats to the validator
279
- */
280
- addCustomFormats(formats) {
281
- if (!formats) return;
282
- Object.entries(formats).forEach(([name, validator]) => {
283
- if (validator instanceof RegExp) {
284
- this.ajv.addFormat(name, validator);
285
- } else {
286
- this.ajv.addFormat(name, { validate: validator });
287
- }
288
- });
289
- }
290
- /**
291
- * Create a validator function with caching
292
- * @param schema - JSON Schema to validate against
293
- * @param cacheKey - Optional cache key for reusing validators
294
- */
295
- createValidator(schema, cacheKey) {
296
- if (cacheKey && !schema.$id) {
297
- schema.$id = cacheKey;
298
- }
299
- if (schema.$id) {
300
- const cached = this.ajv.getSchema(schema.$id);
301
- if (cached) return cached;
302
- }
303
- const validator = this.ajv.compile(schema);
304
- return validator;
305
- }
306
- /**
307
- * Validate data against a schema and return a structured result
308
- */
309
- validate(data, schema, options) {
310
- const validator = this.createValidator(schema, options?.cacheKey);
311
- const valid = validator(data);
312
- if (!valid) {
313
- const errorMessage = this.formatErrors(validator.errors);
314
- if (options?.throwOnError) {
315
- throw new ValidationError(errorMessage, validator.errors || []);
316
- }
317
- return {
318
- valid: false,
319
- errors: validator.errors || void 0,
320
- errorMessage
321
- };
322
- }
323
- return {
324
- valid: true,
325
- data
326
- };
327
- }
328
- /**
329
- * Format errors into a human-readable string
330
- */
331
- formatErrors(errors, options) {
332
- if (!errors || errors.length === 0) {
333
- return "No errors";
334
- }
335
- return this.ajv.errorsText(errors, {
336
- separator: "; ",
337
- dataVar: "data",
338
- ...options
339
- });
340
- }
341
- /**
342
- * Get detailed error information
343
- */
344
- getDetailedErrors(errors) {
345
- if (!errors || errors.length === 0) return [];
346
- return errors.map((error) => ({
347
- field: error.instancePath || "/",
348
- message: error.message || "Validation failed",
349
- keyword: error.keyword,
350
- params: error.params,
351
- schemaPath: error.schemaPath
352
- }));
353
- }
354
- /**
355
- * Add a schema to the validator for reference
356
- */
357
- addSchema(schema, key) {
358
- this.ajv.addSchema(schema, key);
359
- return this;
360
- }
361
- /**
362
- * Remove a schema from the validator
363
- */
364
- removeSchema(key) {
365
- this.ajv.removeSchema(key);
366
- return this;
367
- }
368
- };
369
- var ValidationError = class _ValidationError extends Error {
370
- constructor(message, errors) {
371
- super(message);
372
- this.errors = errors;
373
- this.name = "ValidationError";
374
- Object.setPrototypeOf(this, _ValidationError.prototype);
375
- }
376
- };
377
-
378
- // src/core/server/validation.ts
379
- function initValidator(RED) {
380
- if (RED.validator) return;
381
- const nrg = {
382
- validator: new Validator({
383
- customKeywords: [
384
- {
385
- keyword: "x-nrg-skip-validation",
386
- schemaType: "boolean",
387
- valid: true
388
- },
389
- {
390
- keyword: "x-nrg-node-type",
391
- type: "string",
392
- validate: (schemaValue, dataValue) => {
393
- if (!dataValue) return true;
394
- const node = RED.nodes.getNode(dataValue);
395
- return node?.type === schemaValue;
396
- }
397
- }
398
- ],
399
- customFormats: {
400
- "node-id": /^[a-zA-Z0-9-_]+$/,
401
- "flow-id": /^[a-f0-9]{16}$/,
402
- "topic-path": (data) => /^[a-zA-Z0-9/_-]+$/.test(data)
403
- }
404
- })
405
- };
406
- Object.defineProperty(RED, "_nrg", {
407
- value: nrg,
408
- writable: false,
409
- enumerable: false,
410
- configurable: false
411
- });
412
- Object.defineProperty(RED, "validator", {
413
- get: () => nrg.validator,
414
- enumerable: false,
415
- configurable: false
416
- });
417
- }
418
-
419
- // src/core/server/nodes/symbols.ts
420
- var WIRE_HANDLERS = Symbol.for("nrg.wireHandlers");
421
-
422
238
  // src/test/server/unit/index.ts
239
+ import { initValidator } from "@bonsae/nrg-runtime/internal/server";
240
+ import { WIRE_HANDLERS } from "@bonsae/nrg-runtime/internal/server";
423
241
  import { Kind } from "@sinclair/typebox";
424
242
  function buildConfig(NodeClass, userConfig = {}) {
425
243
  const defaults = {};
package/types/client.d.ts CHANGED
@@ -1,259 +1 @@
1
- // Generated by dts-bundle-generator v9.5.1
2
-
3
- import { Static, TSchema } from '@sinclair/typebox';
4
- import { SchemaObject } from 'ajv';
5
- import { App, Component } from 'vue';
6
-
7
- interface NodeRefResolved<T = any> {
8
- readonly __nrg_node_ref: true;
9
- readonly __instance: T;
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
- }
34
- export interface NodeStateCredentials {
35
- [key: string]: any;
36
- }
37
- export interface NodeState {
38
- credentials: NodeStateCredentials;
39
- [key: string]: any;
40
- }
41
- export interface NodeButtonDefinition {
42
- toggle: string;
43
- onClick: () => void;
44
- enabled?: () => boolean;
45
- visible?: () => boolean;
46
- }
47
- export interface NodeRedNodeButtonDefinition {
48
- toggle: string;
49
- onclick: () => void;
50
- enabled?: () => boolean;
51
- visible?: () => boolean;
52
- }
53
- export interface NodeFormDefinition {
54
- component?: Component;
55
- }
56
- export interface NodeRedNode {
57
- id: string;
58
- type: string;
59
- name: string;
60
- category: string;
61
- x: string;
62
- y: string;
63
- g: string;
64
- z: string;
65
- credentials: Record<string, any>;
66
- _def: {
67
- defaults: Record<string, {
68
- value: string;
69
- type?: string;
70
- label?: string;
71
- required?: boolean;
72
- }>;
73
- credentials: Record<string, {
74
- value: string;
75
- type?: "password" | "text";
76
- label?: string;
77
- required?: boolean;
78
- }>;
79
- category: string;
80
- color?: string;
81
- icon?: string;
82
- label?: ((this: NodeRedNode) => string) | string;
83
- inputs?: number;
84
- outputs?: number;
85
- paletteLabel?: ((this: NodeRedNode) => string) | string;
86
- labelStyle?: ((this: NodeRedNode) => string) | string;
87
- inputLabels?: ((this: NodeRedNode, index: number) => string) | string;
88
- outputLabels?: ((this: NodeRedNode, index: number) => string) | string;
89
- align?: "left" | "right";
90
- button?: NodeRedNodeButtonDefinition;
91
- };
92
- _newState?: NodeRedNode;
93
- _app?: App | null;
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
- /** built-in port toggles, present when declared in the configSchema */
100
- errorPort?: boolean;
101
- completePort?: boolean;
102
- statusPort?: boolean;
103
- /**
104
- * Per-port output settings, indexed by base-output port. `validateOutputs` is
105
- * injected (empty) when the node has an outputsSchema; `outputReturnProperties`
106
- * and `outputContextModes` are author-declared (SchemaType.*) — present only
107
- * when the node opts into per-port return keys / context modes. Read at
108
- * runtime by IONode.
109
- */
110
- validateOutputs?: Record<number, boolean>;
111
- outputContextModes?: Record<number, "carry" | "trace" | "reset">;
112
- outputReturnProperties?: Record<number, string>;
113
- [key: string]: any;
114
- }
115
- export interface NodeDefinition {
116
- type: string;
117
- category?: string;
118
- color?: string;
119
- icon?: ((this: NodeRedNode) => string) | string;
120
- label?: ((this: NodeRedNode) => string) | string;
121
- inputs?: number;
122
- outputs?: number;
123
- paletteLabel?: ((this: NodeRedNode) => string) | string;
124
- labelStyle?: ((this: NodeRedNode) => string) | string;
125
- inputLabels?: ((this: NodeRedNode, index: number) => string) | string;
126
- outputLabels?: ((this: NodeRedNode, index: number) => string) | string;
127
- align?: "left" | "right";
128
- button?: NodeButtonDefinition;
129
- onEditResize?: (this: NodeRedNode, size: {
130
- width: number;
131
- height: number;
132
- }) => void;
133
- onPaletteAdd?: (this: NodeRedNode) => void;
134
- onPaletteRemove?: (this: NodeRedNode) => void;
135
- form?: NodeFormDefinition;
136
- }
137
- /** Form rendering hints carried by the `x-nrg-form` schema keyword. */
138
- export type NrgFormOptions = NonNullable<JsonSchemaObjectExtensions["x-nrg-form"]>;
139
- /**
140
- * A serialized property schema inside {@link JsonSchemaObject} `properties`,
141
- * including NRG's custom keywords (shared vocabulary in core/schema-options)
142
- * that drive form rendering and NodeRef/TypedInput identification.
143
- */
144
- export interface JsonPropertySchema extends JsonSchemaObjectExtensions {
145
- type?: string | string[];
146
- properties?: Record<string, JsonPropertySchema>;
147
- required?: string[];
148
- enum?: unknown[];
149
- anyOf?: JsonPropertySchema[];
150
- const?: unknown;
151
- items?: JsonPropertySchema;
152
- title?: string;
153
- description?: string;
154
- default?: unknown;
155
- }
156
- /**
157
- * A serialized JSON Schema object as the build pipeline emits it (never a
158
- * live TypeBox instance). Extends ajv's `SchemaObject` so it flows into
159
- * validator APIs without casts, while keeping the `type: "object"`
160
- * discriminant and structured `properties`/`required` that ajv's open
161
- * `[x: string]: any` shape does not provide.
162
- */
163
- export interface JsonSchemaObject extends SchemaObject {
164
- type: "object";
165
- properties?: Record<string, JsonPropertySchema>;
166
- required?: string[];
167
- }
168
- /**
169
- * A node definition as it exists at editor runtime, after the build pipeline
170
- * merged in the schema-derived artifacts (defaults, credentials, serialized
171
- * schemas). Authors write {@link NodeDefinition}; the inliner provides the
172
- * rest.
173
- */
174
- export interface RuntimeNodeDefinition extends NodeDefinition {
175
- defaults?: NodeDefaults;
176
- credentials?: NodeCredentials;
177
- configSchema?: JsonSchemaObject;
178
- credentialsSchema?: JsonSchemaObject;
179
- inputSchema?: JsonSchemaObject;
180
- /**
181
- * Single port, positional ports, or named ports (key = port name).
182
- * Not constrained to object schemas: with returnProperty the raw sent
183
- * value is validated, so results may be any schema shape.
184
- */
185
- outputsSchema?: JsonPropertySchema | JsonPropertySchema[] | Record<string, JsonPropertySchema>;
186
- }
187
- export interface NodeDefaults {
188
- [key: string]: {
189
- value: any;
190
- type?: string;
191
- label?: string;
192
- required?: boolean;
193
- validate?: (this: NodeRedNode, value: any, opt: any) => any;
194
- };
195
- }
196
- export interface NodeCredentials {
197
- [key: string]: {
198
- value?: string;
199
- type?: "password" | "text";
200
- label?: string;
201
- required?: boolean;
202
- };
203
- }
204
- export interface NodeFeatures {
205
- hasInputSchema: boolean;
206
- hasOutputSchema: boolean;
207
- /**
208
- * Base output ports (excludes built-in error/complete/status), in port-index
209
- * order. Drives the per-port context-mode rows in the Outputs subsection.
210
- */
211
- outputPorts: {
212
- index: number;
213
- label: string;
214
- }[];
215
- }
216
- /** Client-side representation of a TypedInput field: the raw value string and its type selector. */
217
- export interface TypedInputValue {
218
- value: string;
219
- type: string;
220
- }
221
- /**
222
- * Maps a schema's static type to the raw values the editor form holds.
223
- * The server counterpart (`ResolvedStatic` in server/schemas/types) maps the
224
- * same brands — shared via core/brands — to resolved runtime values instead.
225
- * - `NodeRef<T>` → `string` (the referenced node's id)
226
- * - `TypedInput<T>` → `TypedInputValue` (raw value + type pair)
227
- * - Functions pass through, arrays and objects map recursively
228
- */
229
- 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 ? {
230
- [K in keyof T]: EditorStatic<T[K]>;
231
- } : T;
232
- /**
233
- * Infers the client-side TypeScript type from a TypeBox schema.
234
- *
235
- * Resolves schema types to their client form representations:
236
- * - `NodeRef<T>` → `string` (node ID in the editor)
237
- * - `TypedInput<T>` → `{ value: string; type: string }`
238
- * - All other types resolve via TypeBox's `Static<T>`
239
- *
240
- * @example
241
- * ```ts
242
- * import type { Infer } from "@bonsae/nrg/client";
243
- * import type { ConfigSchema } from "../schemas/my-node";
244
- *
245
- * type Config = Infer<typeof ConfigSchema>;
246
- * ```
247
- */
248
- export type Infer<T extends TSchema> = EditorStatic<Static<T>>;
249
-
250
- export {};
251
-
252
- export declare function defineNode<T extends NodeDefinition>(options: T): T;
253
- export declare function registerType(definition: NodeDefinition): Promise<void>;
254
- export declare function registerTypes(nodes: NodeDefinition[]): Promise<void>;
255
- export declare function useFormNode<TConfig extends TSchema = TSchema, TCredentials extends TSchema = TSchema>(): {
256
- node: NodeRedNode & Infer<TConfig> & { credentials: Infer<TCredentials> & Record<string, any> };
257
- schema: Record<string, any>;
258
- errors: Record<string, string>;
259
- };
1
+ export * from "@bonsae/nrg-runtime/client";