@qoretechnologies/reqraft 0.10.5 → 0.10.7

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.
@@ -154,6 +154,12 @@ function AutoField<T = any>({
154
154
  showSavedValues,
155
155
  uniqueName,
156
156
  componentOverrides,
157
+ // qorus#347-followup (scope forwarding): destructure so it does NOT
158
+ // land in `...rest` — otherwise the primitive field renderers spread
159
+ // rest onto DOM nodes and React warns about the unknown attribute.
160
+ // Only the nested arg_schema mount sites re-forward this into their
161
+ // sub-forms explicitly.
162
+ inheritedFromParent,
157
163
  ...rest
158
164
  }: IAutoFieldProps & T) {
159
165
  const [currentType, setType] = useState<IQorusType>(defaultInternalType || null);
@@ -564,6 +570,20 @@ function AutoField<T = any>({
564
570
  stringTemplates={rest.templates}
565
571
  size={rest.size}
566
572
  disabled={rest.disabled}
573
+ // Forward consumer-injected editors into the nested sub-form
574
+ // so its own fields can render host-injected types (e.g. a
575
+ // `code-editor` override for a `body` sub-field inside a
576
+ // list-of-hash row). Was missing pre-qorus#347-followup —
577
+ // catches an existing gap surfaced by the nested inherit_props
578
+ // story.
579
+ componentOverrides={componentOverrides}
580
+ // qorus#347-followup (scope forwarding): thread the accumulated
581
+ // inheritance bag into the nested sub-form so its own fields'
582
+ // `inherit_props` can reach ancestor-scope values (e.g. a
583
+ // service-method row's `body` picking up `language` from the
584
+ // parent service form). The parent FormEngine populates this
585
+ // via TemplateField -> AutoFormField's `rest`.
586
+ inheritedFromParent={inheritedFromParent}
567
587
  />
568
588
  );
569
589
  }
@@ -658,6 +678,12 @@ function AutoField<T = any>({
658
678
  allowed_values_creatable={rest.element_allowed_values_creatable}
659
679
  type={effectiveElementType}
660
680
  componentOverrides={componentOverrides}
681
+ // qorus#347-followup (scope forwarding): thread the accumulated
682
+ // inheritance bag through the list wrapper so each row's
683
+ // arg_schema sub-form sees it. ArrayAuto forwards this via
684
+ // TemplateField's `rest` into each row's AutoFormField, which
685
+ // hands it to the row's nested FormEngine (case 'hash' above).
686
+ inheritedFromParent={inheritedFromParent}
661
687
  onChange={(name, value) => {
662
688
  if (!size(value)) {
663
689
  return handleChange(name, undefined);
@@ -1,6 +1,6 @@
1
1
  import { StoryObj } from '@storybook/react-vite';
2
- import { expect, fn, userEvent, waitFor, within } from 'storybook/test';
3
2
  import { useState } from 'react';
3
+ import { expect, fn, userEvent, waitFor, within } from 'storybook/test';
4
4
  import { sleep } from '../../../__tests__/utils';
5
5
  import { StoryMeta } from '../../types';
6
6
  import {
@@ -83,14 +83,16 @@ function mockTokenizeQonsole(text: string): number[] {
83
83
  for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {
84
84
  const line = lines[lineIdx];
85
85
  // Strings first so they swallow any `--`/digits inside their quotes.
86
- const TOKEN_RE =
87
- /("(?:\\.|[^"\\])*")|(\d+(?:\.\d+)?)|(--[A-Za-z][\w-]*)|(\/[A-Za-z][\w-]*)/g;
86
+ const TOKEN_RE = /("(?:\\.|[^"\\])*")|(\d+(?:\.\d+)?)|(--[A-Za-z][\w-]*)|(\/[A-Za-z][\w-]*)/g;
88
87
  let match: RegExpExecArray | null;
89
88
  while ((match = TOKEN_RE.exec(line)) !== null) {
90
89
  let type = -1;
91
- if (match[1]) type = 11; // string
92
- else if (match[2]) type = 12; // number
93
- else if (match[3]) type = 9; // modifier — `--flag`
90
+ if (match[1])
91
+ type = 11; // string
92
+ else if (match[2])
93
+ type = 12; // number
94
+ else if (match[3])
95
+ type = 9; // modifier — `--flag`
94
96
  else if (match[4]) type = 8; // keyword — `/verb`
95
97
  if (type >= 0) {
96
98
  tokens.push({
@@ -102,7 +104,7 @@ function mockTokenizeQonsole(text: string): number[] {
102
104
  }
103
105
  }
104
106
  }
105
- tokens.sort((a, b) => (a.line - b.line) || (a.char - b.char));
107
+ tokens.sort((a, b) => a.line - b.line || a.char - b.char);
106
108
  // Delta-encode per LSP spec.
107
109
  const data: number[] = [];
108
110
  let prevLine = 0;
@@ -127,11 +129,7 @@ function setupBasicQonsoleMockServer(): IMockLspServer {
127
129
  experimental: {
128
130
  qonsole: {
129
131
  version: '1.0',
130
- methods: [
131
- 'qonsole/assist',
132
- 'qonsole/validate',
133
- 'qonsole/setContext',
134
- ],
132
+ methods: ['qonsole/assist', 'qonsole/validate', 'qonsole/setContext'],
135
133
  },
136
134
  },
137
135
  },
@@ -213,8 +211,7 @@ function setupBasicQonsoleMockServer(): IMockLspServer {
213
211
  short_desc: 'Guided setup for a new connection',
214
212
  verb: 'create',
215
213
  resource: 'connections',
216
- start_path:
217
- '/api/latest/qonsole/wizards/create-connection/start',
214
+ start_path: '/api/latest/qonsole/wizards/create-connection/start',
218
215
  },
219
216
  command: {
220
217
  title: 'Start Create connection wizard',
@@ -227,8 +224,7 @@ function setupBasicQonsoleMockServer(): IMockLspServer {
227
224
  short_desc: 'Guided setup for a new connection',
228
225
  verb: 'create',
229
226
  resource: 'connections',
230
- start_path:
231
- '/api/latest/qonsole/wizards/create-connection/start',
227
+ start_path: '/api/latest/qonsole/wizards/create-connection/start',
232
228
  },
233
229
  ],
234
230
  },
@@ -237,10 +233,34 @@ function setupBasicQonsoleMockServer(): IMockLspServer {
237
233
  ];
238
234
  } else if (ctx.type === 'resource') {
239
235
  items = [
240
- withTextEdit({ label: 'services', insertText: 'services', kind: 7, detail: 'Service interfaces', commitCharacters: [' '] }),
241
- withTextEdit({ label: 'workflows', insertText: 'workflows', kind: 7, detail: 'Workflow interfaces', commitCharacters: [' '] }),
242
- withTextEdit({ label: 'jobs', insertText: 'jobs', kind: 7, detail: 'Job interfaces', commitCharacters: [' '] }),
243
- withTextEdit({ label: 'users', insertText: 'users', kind: 7, detail: 'IDP users', commitCharacters: [' '] }),
236
+ withTextEdit({
237
+ label: 'services',
238
+ insertText: 'services',
239
+ kind: 7,
240
+ detail: 'Service interfaces',
241
+ commitCharacters: [' '],
242
+ }),
243
+ withTextEdit({
244
+ label: 'workflows',
245
+ insertText: 'workflows',
246
+ kind: 7,
247
+ detail: 'Workflow interfaces',
248
+ commitCharacters: [' '],
249
+ }),
250
+ withTextEdit({
251
+ label: 'jobs',
252
+ insertText: 'jobs',
253
+ kind: 7,
254
+ detail: 'Job interfaces',
255
+ commitCharacters: [' '],
256
+ }),
257
+ withTextEdit({
258
+ label: 'users',
259
+ insertText: 'users',
260
+ kind: 7,
261
+ detail: 'IDP users',
262
+ commitCharacters: [' '],
263
+ }),
244
264
  ];
245
265
  } else if (ctx.type === 'flag') {
246
266
  items = [
@@ -275,9 +295,24 @@ function setupBasicQonsoleMockServer(): IMockLspServer {
275
295
  ];
276
296
  } else if (ctx.type === 'flag-value') {
277
297
  items = [
278
- withTextEdit({ label: 'qorus', insertText: 'qorus', kind: 12, detail: 'Qorus core app' }),
279
- withTextEdit({ label: 'qorus-ide', insertText: 'qorus-ide', kind: 12, detail: 'Qorus IDE' }),
280
- withTextEdit({ label: 'qorus-creator', insertText: 'qorus-creator', kind: 12, detail: 'Qorus Creator' }),
298
+ withTextEdit({
299
+ label: 'qorus',
300
+ insertText: 'qorus',
301
+ kind: 12,
302
+ detail: 'Qorus core app',
303
+ }),
304
+ withTextEdit({
305
+ label: 'qorus-ide',
306
+ insertText: 'qorus-ide',
307
+ kind: 12,
308
+ detail: 'Qorus IDE',
309
+ }),
310
+ withTextEdit({
311
+ label: 'qorus-creator',
312
+ insertText: 'qorus-creator',
313
+ kind: 12,
314
+ detail: 'Qorus Creator',
315
+ }),
281
316
  ];
282
317
  }
283
318
  }
@@ -520,8 +555,7 @@ export const WithDiagnostics: Story = {
520
555
  start: { line: 0, character: 6 },
521
556
  end: { line: 0, character: 14 },
522
557
  },
523
- message:
524
- 'Unknown resource "services" — did you mean "service"?',
558
+ message: 'Unknown resource "services" — did you mean "service"?',
525
559
  severity: 1,
526
560
  },
527
561
  {
@@ -676,9 +710,9 @@ export const WithWizardItems: Story = {
676
710
  () => {
677
711
  const dropdown = document.querySelector('.reqore-menu');
678
712
  expect(dropdown).not.toBeNull();
679
- const item = Array.from(
680
- document.querySelectorAll('.reqore-menu-item')
681
- ).find((el) => el.textContent?.includes('Create connection'));
713
+ const item = Array.from(document.querySelectorAll('.reqore-menu-item')).find((el) =>
714
+ el.textContent?.includes('Create connection')
715
+ );
682
716
  expect(item).toBeDefined();
683
717
  },
684
718
  { timeout: 30000 }
@@ -701,7 +735,6 @@ export const WithWizardItems: Story = {
701
735
  */
702
736
  export const SelectingWizardItemFiresCallback: Story = {
703
737
  args: {
704
- initialValue: '/',
705
738
  onWizardStart: fn(),
706
739
  },
707
740
  parameters: {
@@ -727,23 +760,22 @@ export const SelectingWizardItemFiresCallback: Story = {
727
760
  await userEvent.type(editable, '/');
728
761
  await waitFor(
729
762
  () => {
730
- const item = Array.from(
731
- document.querySelectorAll('.reqore-menu-item')
732
- ).find((el) => el.textContent?.includes('Create connection'));
763
+ const item = Array.from(document.querySelectorAll('.reqore-menu-item')).find((el) =>
764
+ el.textContent?.includes('Create connection')
765
+ );
733
766
  expect(item).toBeDefined();
734
767
  },
735
768
  { timeout: 30000 }
736
769
  );
737
- const wizardItem = Array.from(
738
- document.querySelectorAll('.reqore-menu-item')
739
- ).find((el) => el.textContent?.includes('Create connection'));
770
+ const wizardItem = Array.from(document.querySelectorAll('.reqore-menu-item')).find((el) =>
771
+ el.textContent?.includes('Create connection')
772
+ );
740
773
  await userEvent.click(wizardItem as HTMLElement);
741
774
  // The callback fired with the wizard descriptor...
742
775
  await waitFor(() => expect(args.onWizardStart).toHaveBeenCalled(), {
743
776
  timeout: 30000,
744
777
  });
745
- const callArg = (args.onWizardStart as ReturnType<typeof fn>).mock
746
- .calls[0][0];
778
+ const callArg = (args.onWizardStart as ReturnType<typeof fn>).mock.calls[0][0];
747
779
  expect(callArg).toMatchObject({ action: 'start-wizard' });
748
780
  // ...and NO text was inserted (wizard launch ≠ completion insert).
749
781
  expect(editable.textContent).toBe('/');